文章目录
@bean 定义在静态方法上
当使用上面代码执行时会报警告,提示要加上static
信息: @Bean method MainConfig.customEditorConfigurer is non-static and returns an object assignable to Spring’s BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method’s declaring @Configuration class. Add the ‘static’ modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details.
原因:
以为
customEditorConfigurer类实现了BeanFactoryPostProcessor接口,该接口的方法是容器的后置方法,在容器创建之后就会调用(源码逻辑是创建容器后先扫描是BeanFactoryPostProcessor类型的bean先实例化然后执行实现方法,比普通的bean提前实例化)。如果不是静态,@bean的方法属于实例方法,调用就必须先实例化MainConfig类。如果在MainConfig类中又使用@Autowired等自动注入方法。很有可能所需要的bean这时候并没有实例成功,导致失效。加上静态后,此方法就不属于对象。就可以完美运行。
错误示范
三个bean
@Data
@Component //注册bean
public class Boss {
@Value("CK")
private String name;
}
@Data
//实现容器后置生命周期接口
public class Car implements BeanFactoryPostProcessor{
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("postProcessBeanFactory执行了");
}
}
@Data
public class Com {
private Boss boss;
}
使用配置文件注入(Car没用静态)
@Configuration
@ComponentScan(basePackages = "com.ke.editor")
public class MainConfig {
@Autowired
private Boss boss;
@Bean
public Car car()
{
return new Car();
}
@Bean
public Com com()
{
Com com = new Com();
com.setBoss(boss);
return com;
}
}
使用配置文件注入(Car用静态)
@Configuration
@ComponentScan(basePackages = "com.ke.editor")
public class MainConfig {
@Autowired
private Boss boss;
@Bean
public static Car car()
{
return new Car();
}
@Bean
public Com com()
{
Com com = new Com();
com.setBoss(boss);
return com;
}
}
分别用两个配置执行
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
Com com= (Com)applicationContext.getBean("com");
System.out.println(com);
没使用静态的结果发现输出的com中为null
使用了静态
所以不使用静态,在创建Car之前必须先创建MainConfig对象,创建MainConfig 对象又会将其下面所有@Bean的提前实例化。如果用了自动注入@Autowired(上面的boss对象),这是boss还没有实例化,所以为null,加了静态Car不依赖于MainConfig,只实例化自己
但不是所有加了static的bean都会提前实例化。因为容器只会提前实例化实现了生命周期的接口。普通bean加了也白加。