BeanFactory和FactoryBean有什么区别?
此问题考验的是对spring框架的熟悉度,我们知道spring框架的核心点在于IOC容器,IOC容器的功能就是注入bean,生产bean,而生成bean以工厂模式最好,所以sping就搞了个工厂去专门生成bean,这个工厂就是BeanFactory。
那么什么又是FactoryBean呢?
从名字上看,它就是一个bean,你这么理解它也是没错的,因为它本身具备了一个bean的功能,同时它也是一个接口,只不过它具有一些特殊的功能。以下面的编码来说明:
代码语言:javascript复制/**
* @className: MyFactoryBean
* @Description: TODO 自定义FactoryBean
* @version: v1
* @author: GONGWENXUE
* @date: 2022/5/19 11:46
*/
@Component("MyFactoryBean")
public class MyFactoryBean implements FactoryBean {
/**
* @Author GONGWENXUE
* @Description //TODO 此方法返回要注入的bean,也就是@Component("xx"),
* 外界取值时用"xx" 取到的是getObject()返回的对象
* 如果想取MyFactoryBean,需要在注入的key值前 &,也就是"&xx"
* @version: v1
* @Date 11:48 2022/5/19
* @Param
* @return
**/
@Override
public Object getObject() throws Exception {
System.out.println("返回MyFactoryBean的getObject对象");
Object o = new Object();
return o;
}
@Override
public Class<?> getObjectType() {
return MyFactoryBean.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
测试:
代码语言:javascript复制 public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Object myFactoryBean = context.getBean("myFactoryBean");
System.out.println(myFactoryBean);
}
appConfig:
代码语言:javascript复制@Configuration
public class AppConfig {
@Bean("myFactoryBean")
public MyFactoryBean getMyBean() {
return new MyFactoryBean();
}
}
结果:
从结果中可以看出取到的对象是getObject()中返回的String对象,而不是MyFactoryBean对象。那么如何取原本的MyFactoryBean对象呢?
在注入key值前面 &
从上图可以看出加了&符号就取出了原本的对象。那么spring为啥这么设计呢?
其实这是spring的作者有意向放权给用户,让用户自定义自己的逻辑,因为在现实的项目开发中,有很多第三方的依赖,他们是没有交给spring去管理的,无法使用spring的规则正常的注入到容器中使用,我们也很难使用xml配置文件,或者注解一个个的将第三方依赖,以及第三方的第三方的N多层级依赖都手动注入到spring容器中。这时候就需要一种方式与spring进行对接,于是就有了FactoryBean就诞生了,比如我们常用的Mybatis也是使用了FactoryBean。这种方式的好处就是让第三方依赖于spring容器接入时,不再需要用户去维护第三方依赖所依赖的众多关系,让接入者维护好这些关系,通过FactoryBean再一次性叫给spring去管理。所以mybatis创建了一个
SqlSessionFactory用于维护好mybatis所需要的各种依赖环境,用户只需要将SqlSessionFactory交给spring管理即可。
除此之外,FactoryBean还有两个方法getObjectType()和isSingleton(),他们分别返回对象的类型字节码,和是否单例,完全由用户决定返回的值。
总结:
1.BeanFactory是spring的bean工程,生产管理bean;
2.FactoryBean是一个spring开放给用户自定义bean的接口,以方便第三方技术的接入和自定义的需要。继承FactoryBean的实现类交给spring管理后,会以懒加载的方式,用到的时候才初始化,并产生两个对象注入给spring,其中getObject()的返回值对象以@Component("key")的方式注入,FactoryBean的实现类以@Component("&key")的方式注入。