关于spring:Spring中Component和Configuration的区别
注释首先咱们都晓得应用Spring的@ComponentScan注解能够扫描到@Configuration和@Component的类,并将其交由Spring容器治理,默认会放入单例池中。 新建了一个BeanConfig类用来测试后果: @Configurationpublic class BeanConfig {}复制代码通过上下文获取IOC容器中的BeanConfig,发现的确是被CGLIB进行了代理。 执行查看上下文中beanFactory的单例池中的确存在。 将BeanConfig类的@Configuration注解改为@Component后再看一下则显示没有被CGLIB代理。 问题 那么Spring为什么设计@Configuration注解润饰的Bean要被动静代理? 先说后果:Spring的目标是让@Configuration注解的类中被@Bean注解的办法生成的对象是单例,那如何使一个办法每次生成返回的对象都是同一个,代理就是其中一种形式。 首先@Configuration注解的作用是用于定义配置类来替换XML配置文件,被注解的类外部蕴含有一个或多个被@Bean注解的办法,这些办法会被用于构建BeanDefinition,初始化Spring容器。 也就是说@Configuration的次要目标是搭配@Bean注解代替XML配置文件来向Spring容器注入Bean。咱们在BeanConfig类中减少两个@Bean注解的办法: @Configurationpublic class BeanConfig { //@Scope("prototype") @Bean public Role role(){ return new Role(); } @Bean public User user(){ Role r1=role(); Role r2=role(); System.out.println(r1==r2); return new User(); }}复制代码通过Spring的解决,间接调用 @Configuration 注解中bean 办法,获取的就是同一个对象,这样想要间接应用某个@Bean注解的对象就不须要 @Autowired 注入了。 当然你非要在办法上加上注解@Scope(“prototype”),每次调用该办法还是会生成不同的对象。 源码 注解配置读取器:向BeanDefinitionMap中增加了7个元素,其中一个就是ConfigurationClassPostProcessororg.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext()执行所有的BeanFactoryPostProcessor的postProcessorBeanFactory()办法org.springframework.context.support.AbstractApplicationContext#refresh() 办法中的invokeBeanFactoryPostProcessors(beanFactory)org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanFactory查找到所有带有 @Configuration 注解的 bean 定义,而后在第二个 for 循环中对类进行加强org.springframework.context.annotation.ConfigurationClassPostProcessor#enhanceConfigurationClasses 总结 加了@Configuration的类会被CGLIB进行动静代理,不加或者加@Component注解则不会被代理。