Spring的注解@configuration和@Configurable两者长得非常相似,但用途却有很大的差异。
@configuration 注解大家已经非常熟悉了,配合@bean注解就可以轻松减少xml配置,这里不再过多介绍;
@Configurable 平时用的却较少,它用于解决非Spring容器管理的Bean中却依赖Spring Bean的场景,也就是说Bean A依赖了一个Spring的Bean B,但是A不是Spring 得Bean所以无法进行属性注入拿不到B的情况。
本文就来详细聊一聊这个注解的使用方法和底层原理。
使用方法
在使用之前,咱们先看看@Configurable注解的源码(Spring5.x)
/**
* Marks a class as being eligible for Spring-driven configuration.
*
* <p>Typically used with the AspectJ {@code AnnotationBeanConfigurerAspect}.
*
* @author Rod Johnson
* @author Rob Harrop
* @author Adrian Colyer
* @author Ramnivas Laddad
* @since 2.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Configurable {
/**
* The name of the bean definition that serves as the configuration template.
*/
String value() default "";
/**
* Are dependencies to be injected via autowiring?
*/
Autowire autowire() default Autowire.NO;
/**
* Is dependency checking to be performed for configured objects?
*/
boolean dependencyCheck() default false;
/**
* Are dependencies to be injected prior to the construction of an object?
*/
boolean preConstruction() default false;
}
咱们从源码可以看到,这个注解必须打在类上,Autowire类型默认为Autowire.NO(实际上此值不生效,不需要修改为BY_TYPE也能注入成功,下文会提到)。其他的咱们暂时不用关心。
先新建一个类AA如下:
@Configurable
public class AA {
@Autowired
private BB b;
@Autowired
ApplicationContext applicationContext;
public BB getB() {
return b;
}
public ApplicationContext getApplicationContext() {
return applicationContext;
}
}
AA类增加了注解@Configurable,没有标记@Component等Spring Bean注解,依赖了类BB、ApplicationContext并实现了Getter方法,看看BB类的源码:
@Component
public class BB {
private Long id = 12306L;
public Long getId() {
return id;
}
}
BB类非常简单,@Component标记为Spring扫描类,然后返回id属性的值为12306。
在applicationContext.xml中添加包扫描,注解,aspectj:
<!-- 扫描com.biyao.api.ordergroup下注解 -->
<context:</