美文网首页
springBean内部级联

springBean内部级联

作者: 不存在的里皮 | 来源:发表于2019-05-22 17:52 被阅读0次

阅读Bean官方文档@Bean Methods in @Configuration Classes@Bean Lite Mode小节,可了解spring对Bean内部级联的处理。

什么是内部级联?

参考以下代码,首先我们介绍两个Bean对象,SuperBean 、InnerBean。InnerBean只有一个成员变量number,SuperBean内部持有InnerBean的引用:

public class InnerBean {
    public int number;

    public InnerBean(int number) {
        this.number = number;
    }
}

public class SuperBean {
    public InnerBean innerBean;

    public SuperBean(InnerBean innerBean) {
        this.innerBean = innerBean;
    }
}

然后我们定义一个@Configuration,代码如下。方法superBean()在创建对象时,new SuperBean(innerBean())直接调用了方法innerBean()innerBean()创建对象时,会赋予参数10:

@Configuration // 测试@Configuration
public class InnerBeanReference {
    public static int NUMBER = 10;

    @Bean
    public SuperBean superBean() {
        return new SuperBean(innerBean());
    }

    @Bean
    public InnerBean innerBean() {
        return new InnerBean(NUMBER);
    }
}

当像代码中使用了@Configuration注解时,spring会自动对Bean进行内部级联,什么意思呢?就是当你在别处依赖注入InnerBean时,得到的是SuperBean的内部对象。
为了更好说明,我们看以下代码。代码中,我们使用@Autowired注入了SuperBean和InnerBean:

@SpringBootApplication
public class Application implements CommandLineRunner{

    @Autowired private SuperBean superBean;
    @Autowired private InnerBean innerBean;

    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(Application.class, args);
    }
    
    @Override
    public void run(String... args) throws Exception {
        testSuperBeanWithAutowired();
    }

    public void testSuperBeanWithAutowired() {
        superBean.innerBean.number = 12;
        System.out.println(innerBean.number); // output 12.
    }

}

以上代码执行后,testSuperBeanWithAutowired被调用,并输出12. 可见,注入的innerBean正是superBean的内部对象。

Bean内部级联的触发条件

Bean内部级联只在@Configuration下能生效。如果是在@Component或甚至没有注解的情况下,spring不会进行Bean内部级联。
比如,将上面的类InnerBeanReference的注解@Configuration改为@Component后,其它代码不变,则最后会输出10。

原理

当注解了@Configuration时,为了实现Bean内部级联,spring会使用CGLIB进行动态代理。官方将这个情况称作inter-bean references
当注解为@Component或其它时,spring只会把Bean方法视为普通的工厂方法,不会使用CGLIB进行动态代理。官方将这个情况称作@Bean Lite Mode

总结

  • @Configuration内,spring会自动处理Bean级联问题。
  • @Component等其它注解内,spring只会把Bean方法当做普通工厂方法对待

相关文章

网友评论

      本文标题:springBean内部级联

      本文链接:https://www.haomeiwen.com/subject/nczuzqtx.html