FactoryBean是一个工厂Bean,它本身是spring容器管理的,但他生产的产品只有一部分是spring管理的
@Component("bean1")
public class Bean1FactoryBean implements FactoryBean<Bean1> {
private static final Logger log = LoggerFactory.getLogger(Bean1FactoryBean.class);
// 决定了根据【类型】获取或依赖注入能否成功
@Override
public Class<?> getObjectType() {
return Bean1.class;
}
// 决定了 getObject() 方法被调用一次还是多次
@Override
public boolean isSingleton() {
return true;
}
@Override
public Bean1 getObject() throws Exception {
Bean1 bean1 = new Bean1();
log.debug("create bean: {}", bean1);
return bean1;
}
}
因为spring创建了工厂,而产品是工厂调用getobject方法创建的,也没有调用产品的依赖注入、初始化、回调方法。产品的初始化后会走初始化后的增强方法。
工厂会创建getobject返回的类型的bean,并且beanName是工厂名例如这里的bean1Factory
获取工厂本身的bean:
System.out.println(context.getBean(Bean1FactoryBean.class));
System.out.println(context.getBean("&bean1"));
一个在 Spring 发展阶段中重要, 但目前已经很鸡肋的接口 FactoryBean 的使用要点 说它鸡肋有两点:
1. 它的作用是用制造创建过程较为复杂的产品, 如 SqlSessionFactory, 但 @Bean 已具备等价功能
2. 使用上较为古怪, 一不留神就会用错
- a. 被 FactoryBean 创建的产品 - 会认为创建、依赖注入、Aware 接口回调、前初始化这些都是 FactoryBean 的职责, 这些流程都不会走
- 唯有后初始化的流程会走, 也就是产品可以被代理增强
- 单例的产品不会存储于 BeanFactory 的 singletonObjects 成员中, 而是另一个 factoryBeanObjectCache 成员中
- b. 按名字去获取时, 拿到的是产品对象, 名字前面加 & 获取的是工厂对象 就说恶心不? 但目前此接口的实现仍被大量使用, 想被全面废弃很难