案例:
1.定义Student类:
@Data
public class Student {
private String name;
private Integer age;
public Student() {
}
public Student(String name) {
this.name = name;
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
}
2.定义静态工厂方法/工厂实例方法:
public class StudentStaticFactory {
public static Student getStudent(String name) {
return new Student("悟饭");
}
public static Student getStudent(String name, int age) {
return new Student("悟饭", 22);
}
}
工厂实例方法
public class StudentInstanceFactory {
public Student getStudent(String name) {
Student student = new Student(name);
return student;
}
}
3.定义bean信息;分别定义使用静态工厂方法和实例工厂方法生成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对象; 指定静态工厂方法-->
<bean id ="studentStatic" class="com.cosmos.springdebug.factorymethod.StudentStaticFactory" factory-method="getStudent">
<!--constructor-arg:可以为方法指定参数-->
<constructor-arg value="悟饭"></constructor-arg>
<constructor-arg value="25"></constructor-arg>
</bean>
<!--定义bean对象-->
<bean id="studentInstanceFactory" class="com.cosmos.springdebug.factorymethod.StudentInstanceFactory"></bean>
<!--定义bean对象; 指定工厂bean和实例工厂方法-->
<bean id="student" class="com.cosmos.springdebug.Student" factory-bean="studentInstanceFactory" factory-method="getStudent">
<constructor-arg value="悟天"></constructor-arg>
</bean>
</beans>
4.测试:
public class TestFactoryMethod {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("factoryMethod.xml");
// 获取静态工厂方法中生成的bean对象
Student stu = context.getBean("studentStatic", Student.class);
System.out.println(stu);
// 获取实例工厂方法生成bean对象
Student student = context.getBean("student", Student.class);
System.out.println(student);
}
}
/**
* ==========result=============
* Student(name=悟饭, age=22)
* Student(name=悟天, age=null)
*/
factoryMethod创建bean对象底层源码逻辑:
真正执行bean创建方法doCreateBean
;所以这里主要梳理doCreateBean中执行工厂实例方法和工厂静态方法创建bean对象流程:
使用factoryMethod创建bean底层流程图:
instantiateUsingFactoryMethod底层实现逻辑:
instantiateUsingFactoryMethod方法实现流程图:
总结:
通过BeanDefinition属性factoryMethod创建bean对象是spring创建对象的5种方式之一;这种方式更为灵活,可以自行定义bean对象的生成方法;不局限于需要实现指定的接口和方法!关于BeanWrapperImpl包装对象设置了相关的类型转换服务;类型转换是创建bean对象封装到包装对象的重要作用!