BeanFactory
BeanFactory, 它是负责生产和管理 bean 的一个工厂。也可以理解为 bean 的注册中心。它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。他是IOC容器的核心接口之一。它有很多实现类如:DefaultListableBeanFactory
FactoryBean
官方文档: Customizing Instantiation Logic with a FactoryBean
基本描述
- FactoryBean 也是一个由 Spring 容器管理的类,其可以通过 BeanFactory 的 getBean 方法获得;
- 它起到一个工厂的作用,可以通过 getObject 来生产 bean ;
- 在首字母小写前面加一个&符号,获得的是 FactoryBean 实例;
- FactoryBean 不支持依赖注入,它调用时机在 Spring 初始化的早期进行,此时还没有生成要依赖的对象;
- 调用时该 FactoryBean 尚未完全初始化,则抛出相应的FactoryBeanNotInitializedException;
存在的原因?
spring 通过 xml 配置或者注解,利用反射等机制已经能实现 bean 的实例化,为什么还需要 FactoryBean 来生产 bean ?
- 首先 通过配置文件来配置 bean ,在一些复杂的情况下,配置并不能满足各种各样的需求,如果使用FactoryBean,通过接口注册,就能通过代码自定义实现各种复杂 bean 的实例化。
- 除外,通过接口也给了第三方扩展的可能。
测试代码
自定义个 FactoryBean
public class UserFactoryBean implements FactoryBean<User> {
private static final User instance = new User();
@Override
public User getObject() throws Exception {
instance.setName("nb!");
return instance;
}
@Override
public Class<?> getObjectType() {
return User.class;
}
}
注册 bean
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "https://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="userFactoryBean" class="cn.lichenghao.factory.UserFactoryBean"></bean>
</beans>
测试
public class AppFactoryBean {
public static void main(String[] args) {
// 根据配置文件加载bean
ClassPathXmlApplicationContext context
= new ClassPathXmlApplicationContext("factoryBean.xml");
// 直接获取userFactoryBean得到的是其getObject返回的对象
Object obj1 = context.getBean("userFactoryBean");
// 加&前缀,获取到FactoryBean实例
Object obj2 = context.getBean("&userFactoryBean");
System.out.println(obj1);
System.out.println(obj2);
}
}
// 运行结果
> Task :spring-lich-test:AppFactoryBean.main()
User{name='nb!', age='null'}
cn.lichenghao.factory.UserFactoryBean@1e88b3c