二者关系
首先,都是用来创建对象的,如果是使用BeanFactroy接口,那么必须要严格遵守springBaen的生命周期接口,从实例化到初始化,到invokeAwareMethod、invokeInitMethod、before、after,此流程非常复杂且麻烦,如果需要一种更加便捷简单的方式创建,怎么办?所以有了FactoryBean接口,不需要遵循此创建顺序。
Factroy介绍
factory有三个接口,如下图所示:
Factory细节
1、FactoryBean的getObject对象返回的实例,在spring容器初始化的时候不会加载,只会在调用的时候加载。
2、FactoryBean本身会被加载到spring容器中,如果需要获取需要在名称前加上”&“符号
getObject('name')返回工厂中的实例
getObject('&name')返回工厂本身的实例
3、两个对象在spring容器中所放的缓存不同,实现了FactoryBean接口的对象在一级缓存中。但是调用getObject()方法获取的对象在factoryBeanObjectCache中,如果不是单例对象的话,那么需要每次调用的时候重新创建,缓存中不会保存当前对象。
简单使用
0、创建一个实体类
public class Student {
private Long id;
private String name;
private int age;
}
1、创建一个类实现FactoryBean接口
import org.springframework.beans.factory.FactoryBean;
/**
* @author LongFei
*/
public class MyFactoryBean implements FactoryBean<Student> {
//获取一个对象
public Student getObject() {
return new Student();
}
//获取类型
public Class<?> getObjectType() {
return null;
}
//是否为单例模式
public boolean isSingleton() {
return true;
}
}
2、创建一个配置文件factoryBean.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">
<bean id="myFactoryBean" class="com.fei.factoryBean.MyFactoryBean">
</bean>
</beans>
3、创建测试类
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("factoryBean.xml");
//获取getObject返回的对象
Student student = (Student) ac.getBean("myFactoryBean");
System.out.println(student);
//获取本身
MyFactoryBean myFactoryBean = (MyFactoryBean) ac.getBean("&myFactoryBean");
System.out.println(myFactoryBean);
}
}
4、控制台打印
分析
此时在容器刚刚初始化,可以看到beanFactory中的BeanDefinitionMap中是仅仅存在MyFactoryBean本身一个实例的。
当去get的时候,才会加载getObject中的方法,如果是单例的,那么同时也会放到缓存中,后续再get的时候就直接从缓存中获取。