spring使用记录

@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加了也白加。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值