Spring系统学习 - FactoryBean和基于XML的自动装配

2024-06-20 16:52

本文主要是介绍Spring系统学习 - FactoryBean和基于XML的自动装配,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Factory Bean

Spring的FactoryBean是一个特殊的Bean,用于创建其他Bean实例。FactoryBean接口定义了一个工厂Bean,该Bean可以用来生成其他Bean的实例。通过实现FactoryBean接口,开发人员可以自定义Bean的创建逻辑,实现更灵活的Bean实例化过程。

FactoryBean是Spring提供的一种整合第三方框架的常用机制。和普通的bean不同,配置一个FactoryBean类型的bean,在获取bean的时候得到的并不是class属性中配置的这个类的对象,而是getObject()方法的返回值。通过这种机制,Spring可以帮我们把复杂组件创建的详细过程和繁琐细节都屏蔽起来,只把最简洁的使用界面展示给我们。

public interface FactoryBean<T> {String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";//返回由FactoryBean创建的Bean实例。@NullableT getObject() throws Exception;//返回由FactoryBean创建的Bean实例的类型。@NullableClass<?> getObjectType();//返回由FactoryBean创建的Bean实例是否是单例的。default boolean isSingleton() {return true;}}

在这里插入图片描述

通过实现FactoryBean接口,开发人员可以自定义Bean的创建过程,实现一些复杂的逻辑,例如对象的缓存、对象的代理等。在Spring中,FactoryBean常用于定制化Bean的创建过程,提供更灵活的Bean管理方式。

案例演示

我们的案例演示将使用上一讲的Spring的bean的生命周期的实例,在我们已经创建好的实例上进行相关处理。

实体类

public class User {private Integer id;private String username;private String password;private Integer age;public User() {System.out.println("生命周期:1、创建对象");}public User(Integer id, String username, String password, Integer age) {this.id = id;this.username = username;this.password = password;this.age = age;}public Integer getId() {return id;}public void setId(Integer id) {System.out.println("生命周期:2、依赖注入");this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public void initMethod(){System.out.println("生命周期:3、初始化");}public void destroyMethod(){System.out.println("生命周期:5、销毁");}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +", age=" + age +'}';}}

XML文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 使用init-method属性指定初始化方法 --><!-- 使用destroy-method属性指定销毁方法 --><bean id="userFactory" class="com.miaow.spring.bean.User" init-method="initMethod" destroy-method="destroyMethod"><property name="id"  value="257258"></property><property name="age" value="25"></property><property name="password" value="wwafheda"></property><property name="username" value="张老三"></property></bean><bean id="myBeanProcessor" class="com.miaow.spring.process.MyBeanProcessor"></bean><!--    配置bean FactoryBeam--><bean id="userFactoryBean" class="com.miaow.spring.factory.UserFactoryBean"></bean></beans>

UserFactoryBean

/*** @author HWZ* @date 2024年05月11日 10:36* @description FactoryBean 是Spring提供的一种整合第三方框架的常用机制,和普通bean不同,配置一个FactoryBean类型的bean,*  Spring会调用FactoryBean的getObject()方法来获取一个实例,而不是直接new一个对象。*  FactoryBean的getObject()方法返回的是一个实例,而不是一个类。*  FactoryBean的getObjectType()方法返回的是一个类,而不是一个实例*/
public class UserFactoryBean implements FactoryBean<User> {@Overridepublic User getObject() throws Exception {return new User();}@Overridepublic Class<?> getObjectType() {return User.class;}@Overridepublic boolean isSingleton() {return FactoryBean.super.isSingleton();}
}

后置处理器

public class MyBeanProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("☆☆☆" + beanName + " = " + bean);return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("★★★" + beanName + " = " + bean);return bean;}
}

测试

    //factorty测试@Testpublic void FactoryTest(){ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean-factory.xml");User user = (User) context.getBean("userFactory");System.out.println(user);System.out.println("生命周期:4、通过IOC容器获取bean并使用");context.close();}

在这里插入图片描述
在这里插入图片描述

基于XML的自动装配

Spring的自动装配是一种通过Spring容器自动连接应用程序中的Bean的方式。当Bean定义了依赖关系时,Spring容器可以自动识别这些依赖关系,并自动将相应的Bean注入到目标Bean中,从而实现Bean之间的自动连接。

目前Spring中提供自动装配的方式分为如下三种:

  • 根据类型自动装配:Spring 容器会自动匹配Bean的类型,将符合类型要求的Bean注入到目标Bean中。
  • 根据名称自动装配:Spring 容器会自动匹配Bean的名称,将符合名称要求的Bean注入到目标Bean中。
  • 构造函数自动装配:Spring 容器会自动识别目标Bean的构造函数,并自动将依赖的Bean注入到构造函数当中。

模拟实现

我们通过一个实例来看一下Spring 的自动装配方式,首先我们创建一个我们常用的开发层。

创建一个控制层

public class UserController {private UserService userService;public void setUserService(UserService userService) {this.userService = userService;}public void saveUser(){userService.saveUser();}
}

创建接口UserService

public interface UserService {void saveUser();
}

创建Service接口实现层

public class UserServiceImpl implements UserService {private UserDao userDao;public void setUserDao(UserDao userDao) {this.userDao = userDao;}@Overridepublic void saveUser() {userDao.saveUser();}
}

创建dao层接口

public interface UserDao {void saveUser();
}

创建类dao层实现层

public class UserDaoImpl implements UserDao {@Overridepublic void saveUser() {System.out.println("保存成功");}
}

根据类型自动装配(byType)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--    spring IOC的自动装配  根据指定的策略,在IOC容器中匹配某一个bean,自动为指定的bean中所依赖的类类型或接口类
自动装配方式:byType
byType:根据类型匹配IOC容器中的某个兼容类型的bean,为属性自动赋值
若在IOC中,没有任何一个兼容类型的bean能够为属性赋值,则该属性不装配,即值为默认值null
若在IOC中,有多个兼容类型的bean能够为属性赋值,则抛出异常NoUniqueBeanDefinitionException自动装配方式:byName
byName:将自动装配的属性的属性名,作为bean的id在IOC容器中匹配相对应的bean进行赋值--><bean id="userController" class="com.miaow.spring.controller.UserController" autowire="byType"></bean><!--    配置 service层--><bean id="userService" class="com.miaow.spring.service.impl.UserServiceImpl" autowire="byType"></bean><!--    配置dao层--><bean id="userDao" class="com.miaow.spring.dao.impl.UserDaoImpl"></bean>
</beans>
    //自动装配 通过注解的方式ByType 和 ByName装配@Testpublic void AutoWireTest(){ApplicationContext context = new ClassPathXmlApplicationContext("spring-user.xml");UserController user = (UserController) context.getBean(UserController.class);user.saveUser();}

在这里插入图片描述

根据名称注入(byName)

    <bean id="userController" class="com.miaow.spring.controller.UserController" autowire="byName"></bean><bean id="userService" class="com.miaow.spring.service.impl.UserServiceImpl" autowire="byName"></bean>

在这里插入图片描述

构造器注入

我们需要创建一个实体类,用来存储我们在XML配置文件中通过构造器注入的相关值。

在Java类中定义相应的构造函数,Spring容器会根据XML配置文件中的<constructor-arg>元素来自动注入参数值。

public class MyBean {private int number;private AnotherBean anotherBean;public MyBean(int number, AnotherBean anotherBean) {this.number = number;this.anotherBean = anotherBean;}public int getNumber() {return number;}public void setNumber(int number) {this.number = number;}public AnotherBean getAnotherBean() {return anotherBean;}public void setAnotherBean(AnotherBean anotherBean) {this.anotherBean = anotherBean;}@Overridepublic String toString() {return "MyBean{" +"number=" + number +", anotherBean=" + anotherBean +'}';}
}
public class AnotherBean {private int number;public int getNumber() {return number;}public void setNumber(int number) {this.number = number;}@Overridepublic String toString() {return "AnotherBean{" +"number=" + number +'}';}
}
<!--  构造方法注入  --><bean id="myBean" class="com.miaow.spring.bean.MyBean"><constructor-arg value="123" type="int"/><constructor-arg ref="anotherBean"/></bean><bean id="anotherBean" class="com.miaow.spring.bean.AnotherBean"/>
    public void AutoWireTest(){ApplicationContext context = new ClassPathXmlApplicationContext("spring-user.xml");MyBean myBean = (MyBean) context.getBean("myBean");System.out.println(myBean);

在这里插入图片描述

这篇关于Spring系统学习 - FactoryBean和基于XML的自动装配的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1078705

相关文章

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

SpringBoot中使用 ThreadLocal 进行多线程上下文管理及注意事项小结

《SpringBoot中使用ThreadLocal进行多线程上下文管理及注意事项小结》本文详细介绍了ThreadLocal的原理、使用场景和示例代码,并在SpringBoot中使用ThreadLo... 目录前言技术积累1.什么是 ThreadLocal2. ThreadLocal 的原理2.1 线程隔离2

springboot将lib和jar分离的操作方法

《springboot将lib和jar分离的操作方法》本文介绍了如何通过优化pom.xml配置来减小SpringBoot项目的jar包大小,主要通过使用spring-boot-maven-plugin... 遇到一个问题,就是每次maven package或者maven install后target中的ja

Java中八大包装类举例详解(通俗易懂)

《Java中八大包装类举例详解(通俗易懂)》:本文主要介绍Java中的包装类,包括它们的作用、特点、用途以及如何进行装箱和拆箱,包装类还提供了许多实用方法,如转换、获取基本类型值、比较和类型检测,... 目录一、包装类(Wrapper Class)1、简要介绍2、包装类特点3、包装类用途二、装箱和拆箱1、装

如何利用Java获取当天的开始和结束时间

《如何利用Java获取当天的开始和结束时间》:本文主要介绍如何使用Java8的LocalDate和LocalDateTime类获取指定日期的开始和结束时间,展示了如何通过这些类进行日期和时间的处... 目录前言1. Java日期时间API概述2. 获取当天的开始和结束时间代码解析运行结果3. 总结前言在J

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

Java多线程父线程向子线程传值问题及解决

《Java多线程父线程向子线程传值问题及解决》文章总结了5种解决父子之间数据传递困扰的解决方案,包括ThreadLocal+TaskDecorator、UserUtils、CustomTaskDeco... 目录1 背景2 ThreadLocal+TaskDecorator3 RequestContextH

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创

关于Spring @Bean 相同加载顺序不同结果不同的问题记录

《关于Spring@Bean相同加载顺序不同结果不同的问题记录》本文主要探讨了在Spring5.1.3.RELEASE版本下,当有两个全注解类定义相同类型的Bean时,由于加载顺序不同,最终生成的... 目录问题说明测试输出1测试输出2@Bean注解的BeanDefiChina编程nition加入时机总结问题说明