这个步骤在createBeanInstance()方法中有使用,我们先来看下这个方法中都干了些啥(。・ω・。)ノ 首先,方法开头确认了beanClass是否被加载(因为只有被加载叻的对象才是可以实例化的)
然后,判断当前beanDefinition中是否包含实例供应器,此步骤如果instanceSupplier!=null的话,则会直接通过obtainFromSupplier(instanceSupplier, beanName);方法直接返回一个Bean的包装类BeanWrapper而不会再进行下面的逻辑叻(保姆级测试教程戳戳
【保姆级·创建对象】如何通过Supplier创建对象_AQin1012的博客-CSDN博客
)
所以只有在不满足这一条判断的前提下,才会进入我们今天要分析的使用factory-method
创建对象
来~开始٩(˃̶͈̀௰˂̶͈́)و
首先,需要啰嗦下通过工厂模式创建实例对象主要有两种方式:
静态工厂(无需工厂的实例对象)
实例工厂(需要创建工厂的实例对象)
所以本案例中我们创建了两个工厂类(静态工厂类:StudentStaticFactory.java和实例工厂类:StudentInstanceFactory.java)
public class Student {private String name;private Integer age;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}
}
public class StudentStaticFactory {public static Student getStudent(String name) {Student student = new Student();student.setName(name);student.setAge(88);return student;}
}
public class StudentInstanceFactory {public Student getStudent(String name) {Student student = new Student();student.setName(name);student.setAge(88);return student;}
}
参数说明
factory-bean="personStaticFactory":指定使用的工厂实例是"personStaticFactory"
factory-method="getStudent":指定使用的工厂实例的方法为"getStudent"
constructor-arg value="aqin":为方法指定参数
public class TestFactoryMethod {public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("factoryMethod.xml");Student bean = applicationContext.getBean("student", Student.class);System.out.println(bean.getName());System.out.println("-------------------------------");Student bean2 = applicationContext.getBean("student2", Student.class);System.out.println(bean2.getName());}
}
在使用工厂方法初始化策略的位置打个断点,如下图
默认情况(在未创建案例中的文件时),会发现mbd.getFactoryMethodName()=null,不会进入if的逻辑中
当执行案例中的测试方法
会发现,此时mbd.getFactoryMethodName()="getStudent",所以我们进入了if的逻辑中(*≧ω≦) 点击进入,进入instantiateUsingFactoryMethod()方法中(这里先捋下执行逻辑,后续会对这个方法做详细介绍,毕竟行数300+的方法,值得单独拎出来瞅瞅(˶‾᷄ ⁻̫ ‾᷅˵)),instantiateUsingFactoryMethod()方法是通过一个命名的工厂方法来实例化Bean的,会返回一个Bean的包装类BeanWrapper
然后就不会再向下继续,而会直接回到createBeanInstance()方法中,继续后面的包装以及初始化的逻辑