如果存在当前bean的FactoryBean, spring认为诸如依赖注入、初始化、Aware等这些生命阶段都应该有FactoryBean种处理, 所以即使这里配置了都不会生效
准备bean以及生命周期阶段实现
@Slf4j
public class Bean1 implements BeanFactoryAware {
private Bean2 bean2;
@Autowired
public void setBean2(Bean2 bean2) {
log.warn("setBean2({})", bean2);
this.bean2 = bean2;
}
public Bean2 getBean2() {
return bean2;
}
@PostConstruct
public void init() {
log.warn("init");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
log.warn("setBeanFactory({})", beanFactory);
}
}
@Component
public class Bean2 {
}
准备BeanPostProcessor
@Slf4j
@Component
public class Bean1PostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 初始化前操作也不会执行
if ("bean1".equals(beanName) && bean instanceof Bean1) {
log.warn("before [{}] init", beanName);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 初始化后操作会执行
if ("bean1".equals(beanName) && bean instanceof Bean1) {
log.warn("after [{}] init", beanName);
}
return bean;
}
}
准备FactoryBean
@Slf4j
@Component("bean1")
public class Bean1FactoryBean implements FactoryBean<Bean1> {
@Override
public Bean1 getObject() throws Exception {
Bean1 bean1 = new Bean1();
log.warn("createBean1:{}", bean1);
return bean1;
}
@Override
public Class<?> getObjectType() {
// applicationContext.getBean(Bean1.class) 需要此方法返回类型 否则return null就会报错
// return null;
return Bean1.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
测试
@ComponentScan
public class TestFactoryBean {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(TestFactoryBean.class);
Bean1 bean1 = (Bean1) applicationContext.getBean("bean1");
Bean1 bean2 = (Bean1) applicationContext.getBean("bean1");
Bean1 bean3 = (Bean1) applicationContext.getBean("bean1");
System.out.println(bean1);
System.out.println(bean2);
System.out.println(bean3);
// getObjectType#getObjectType方法需要返回类型
System.out.println(applicationContext.getBean(Bean1.class));
// 获取Bean1FactoryBean的方式
System.out.println(applicationContext.getBean(Bean1FactoryBean.class));
System.out.println(applicationContext.getBean("&bean1"));
applicationContext.close();
}
}
小结
- 被FactoryBean创建的产品
- 会认为创建、依赖注入、Aware接口回调、前初始化这些都是FactoryBean的职责,这些流程都不会执
- 唯有后初始化的流程会走,也就是bean可以被代理增强
- 单例的产品不会存储于BeanFactory的singletonObjects成员中,而是另一个factoryBeanObjectCache成员中
- 按名字去获取时,拿到的是产品对象,名字前面加 & 获取的是工厂对象