在Spring中Bean的实例化由三种
创建一个实体类Person1
public class Person1 {
}
使用该类的默认构造器实例化Bean
配置文件:
<?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">
<bean id="person" class="com.lyl.testBean.Person1"/>
</beans>
测试类:
public static void main(String[] args) {
// 初始化Spring容器,加载配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext1.xml");
System.out.println(context.getBean("person");
}
打印结果:
com.lyl.testBean.Person1@50f8360d
这个应该是最直接的,也是最简单的实例化Bean了(在Spring中)。
创建静态工厂类:
// 静态工厂类
public class MyStaticBeanFactory {
// 创建Bean实例化的工厂方法
public static Person1 createPerson1(){
return new Person1();
}
}
配置文件:
<?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">
<!-- class指向的是静态工厂类的全限定类名,factory-method指向的是调用静态工厂类的createPerson1()方法获取Bean实例 -->
<bean id="person" class="com.lyl.testBean.MyStaticBeanFactory" factory-method="createPerson1"/>
</beans>
测试类:
public static void main(String[] args) {
// 初始化Spring容器,加载配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext2.xml");
System.out.println(context.getBean("person"));
}
打印结果:
com.lyl.testBean.Person1@174d20a
定义了id为person
的Bean,class指定的是静态工厂类的全限定类名,而factory-method
是通知Spring容器调用静态工厂类的createPerson1()
方法的带Bean的实例。
可能看起来稍微难理解一点点,其实就是本质就是调用了静态工厂的createPerson1()
方法,而Bean是什么?Bean说到底了了也是一个Java类,Spring在期间只是调用了方法而已,如果有返回值便会把返回值传递给Bean,那么工厂的静态方法如果没有返回值怎么办?会报错!
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘person‘ defined in class path resource [applicationContext2.xml]: Invalid factory method ‘createPerson1‘: needs to have a non-void return type!
线程“main”org.springframework.beans.factory.bencreationException中出现异常:创建在类路径资源[applicationContext2.xml]中定义的名为“person”的bean时出错:无效的工厂方法“createPerson1”:需要具有非空返回类型!
可以看到Spring不允许没有返回值,也就是该方法必须要有返回值!修饰词不能为void
。
创建实例化工厂类:
public class MyBeanFactory {
MyBeanFactory(){
System.out.println("person1工厂实例化中。。。");
}
public Person1 createPerson1(){
return new Person1();
}
}
配置文件:
<?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">
<bean id="myFactory" class="com.lyl.testBean.MyBeanFactory"/>
<bean id="person" factory-bean="myFactory" factory-method="createPerson1"/>
</beans>
测试类:
public static void main(String[] args) {
// 初始化Spring容器,加载配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext3.xml");
System.out.println(context.getBean("person"));
}
打印结果:
person1工厂实例化中。。。
com.lyl.testBean.Person1@174d20a
这个看起来就比静态工厂类实例化Bean更复杂一点了,那么我们不妨单独提出来看看。
我们知道在工厂类中想得到Person1
类的对象只能调用createPerson1()
方法,而这个方法又不是上面的静态方法,所以我们还需要得到工厂类的实例才能调用方法。OK!那么我们就知道了得到Person1
类的对象需要先创建实例化工厂类的对象。
id为myFactory
的Bean,class指定的是实例化工厂类的全限定类名,干嘛的?是不是有点像构造方法实例化Bean?
id为person
的Bean多了两个属性(factory-bean、factory-method)少了常见的class属性。
与之前两个获取Bean方法的测试类没有区别,说明我们在测试类中视觉上是加载了id为person
的Bean,但是再看配置文件中为person
的Bean并没有class指定的全限定类名,反而多了factory-bean
这个属性。
factory-bean
——工厂(顾名思义,factory-bean就是生成bean的工厂对象,factory-bean属性和factory-method属性一起使用,首先要创建生成bean的工厂类和方法。)
那么最终是怎么得到Person1类对象的呢?
通知Spring加载id为person
的Bean,检查到有factory-bean
属性和factory-method
属性,又去查找id为factory-bean
中的值(myFactory)的Bean并根据class属性初始化,再根据factory-method
属性中的值的方法去工厂类中调用并传递返回值。这就是我理解的实例化工厂类实例化Bean的过程。我理解的肯定不是完全正确的,但是至少能帮助我们前期理解其中的表层运行过程,后面肯定是需要我们运用到实际项目中去实践,再去总结。
原文:https://www.cnblogs.com/cndada/p/14721211.html