@Component,和@Component异同点
相同点:
- 可以标识该类实例被Spring-ioc容器管理
- 类中含有@Bean的方法,可以创建bean
- 作为配置类
不同点:
- @Configuration中所有带
@Bean
注解的方法都会被CGlib动态代理,因此调用该方法返回的都是同一个实例
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
@AliasFor(
annotation = Component.class
)
String value() default "";
boolean proxyBeanMethods() default true;
}
@Configuration注解
2. @Conponent 修饰的类不会被代理,每实例化一次就会创建一个新的对象。
@Configuration 标记的类必须符合下面的要求:
- 配置类必须以类的形式提供(不能是工厂方法返回的实例),允许通过生成子类在运行时增强(cglib 动态代理)。
- 配置类不能是 final 类(没法动态代理)。
- 配置注解通常为了通过 @Bean 注解生成 Spring 容器管理的类,
- 配置类必须是非本地的(即不能在方法中声明,不能是 private)。
- 任何嵌套配置类都必须声明为static。
- @Bean 方法可能不会反过来创建进一步的配置类(也就是返回的 bean 如果带有 @Configuration,也不会被特殊处理,只会作为普通的 bean)。
@Configuration 注解定义的 bean 方法中可以直接调用方法,不需要 @Autowired 注入后使用。
因为源码是直接调用CGlib动态代理的代理类,obtainBeanInstanceFromFactory 方法比较简单,就是通过 beanFactory.getBean 获取 Country,如果已经创建了就会直接返回,如果没有执行过,就会通过 invokeSuper 首次执行。
具体底层的实现原理可以去看一看这篇文章:configuration和component区别底层实现
@Bean注解
Spring的@Bean注解用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次,随后这个Spring将会将这个Bean对象放在自己的IOC容器中。
- value: name属性的别名,在不需要其他属性时使用,也就是说value 就是默认值
- name: 此bean 的名称,或多个名称,主要的bean的名称加别名。如果未指定,则bean的名称是带注解方法的名称。如果指定了,方法的名称就会忽略,如果没有其他属性声明的话,bean的名称和别名可能通过value属性配置