@Autowired 支持set方法,构造方法,参数的注入。下面我们了解一下它的工作原理。
文章目录
- 1.解析@Autowired的类AutowiredAnnotationBeanPostProcessor
- 2. 调用AutowiredAnnotationBeanPostProcessor的方法流程
- 3. AutowiredAnnotationBeanPostProcessor中注入方法的解析
- 4. 构造函数注入
1.解析@Autowired的类AutowiredAnnotationBeanPostProcessor
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware
spring中通过AutowiredAnnotationBeanPostProcessor来解析注入注解为目标注入值。该class实现了InstantiationAwareBeanPostProcessorAdapter,MergedBeanDefinitionPostProcessor接口,重写的方法将在IOC创建bean的时候被调用。
2. 调用AutowiredAnnotationBeanPostProcessor的方法流程
刚才已经提到了是spring创建bean的时候调用,即
当使用DefaultListableBeanFactory来获取想要的bean的时候。如下:
调用的是AbstractBeanFactory中的getBean方法,继续追踪源码最后在AbstractAutowireCapableBeanFactory类中的createBean方法中找到了调用解析@autowired的方法:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
...
...
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); // 调用postProcessMergedBeanDefinition方法
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
... ...
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper); // 调用postProcessAfterInstantiation方法postProcessPropertyValues方法
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
...
...
然后来看AutowiredAnnotationBeanPostProcessor的两个类做了些什么
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanType != null) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null); // 从缓存中获取InjectionMetadata,未取到则构造注入的metadata
metadata.checkConfigMembers(beanDefinition);
}
}
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
Class<?> targetClass = clazz;
do {
final LinkedList<InjectionMetadata.InjectedElement> currElements =
new LinkedList<InjectionMetadata.InjectedElement>();
// 成员变量
ReflectionUtils.doWithLocalFields(targetClass, new ReflectionUtils.FieldCallback() {
@Override
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
AnnotationAttributes ann = findAutowiredAnnotation(field); // 获取成员变量中带有注入注解(@Autowired,@value,@inject)并加入AnnotationAttributes列表
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static fields: " + field);
}
return;
}
boolean required = determineRequiredStatus(ann); // required属性是false or true
currElements.add(new AutowiredFieldElement(field, required)); // 添加到注入列表
}
}
});
// 方法
ReflectionUtils.doWithLocalMethods(targetClass, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); // 有桥接方法的返回桥接方法的最原始方法,否则返回自身
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod); // 获取方法上带有注入注解(@Autowired,@value,@inject)并加入AnnotationAttributes列表
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) { // 检测合法性
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterTypes().length == 0) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
boolean required = determineRequiredStatus(ann); // required属性是false or true
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); // 获取目标class中某成员拥有读或写方法与桥接方法一直的PropertyDescriptor
currElements.add(new AutowiredMethodElement(method, required, pd)); // 添加到注入列表
}
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass(); // 有父类继续解析
}while (targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements); // 返回需要注入的信息
}
具体注入postProcessPropertyValues:
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); // 从缓存中获取InjectionMetadata,未取到则构造注入的metadata
try {
metadata.inject(bean, beanName, pvs); // 具体注入
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
// 注入
public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable {
Collection<InjectedElement> elementsToIterate =
(this.checkedElements != null ? this.checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
boolean debug = logger.isDebugEnabled();
for (InjectedElement element : elementsToIterate) {
if (debug) {
logger.debug("Processing injected element of bean '" + beanName + "': " + element);
}
element.inject(target, beanName, pvs); // 真实注入
}
}
}
/**
* Either this or {@link #getResourceToInject} needs to be overridden.
*/
protected void inject(Object target, String requestingBeanName, PropertyValues pvs) throws Throwable {
if (this.isField) {
// 注解加在成员上的,注入成员参数
Field field = (Field) this.member;
ReflectionUtils.makeAccessible(field);
field.set(target, getResourceToInject(target, requestingBeanName));
}
else {
if (checkPropertySkipping(pvs)) {
return;
}
try {
// 注解加在方法上的,调用方法注入
Method method = (Method) this.member;
ReflectionUtils.makeAccessible(method);
method.invoke(target, getResourceToInject(target, requestingBeanName));
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
3. AutowiredAnnotationBeanPostProcessor中注入方法的解析
看一下postProcessMergedBeanDefinition方法和postProcessPropertyValues干了什么
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanType != null) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null); // 从缓存中获取InjectionMetadata,未取到则构造注入的metadata信息
metadata.checkConfigMembers(beanDefinition);//
}
}
// 构造metadata
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
Class<?> targetClass = clazz;
do {
final LinkedList<InjectionMetadata.InjectedElement> currElements =
new LinkedList<InjectionMetadata.InjectedElement>();
// 成员变量
ReflectionUtils.doWithLocalFields(targetClass, new ReflectionUtils.FieldCallback() {
@Override
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
AnnotationAttributes ann = findAutowiredAnnotation(field); // 获取成员变量中带有注入注解(@Autowired,@value,@inject)并加入AnnotationAttributes列表
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static fields: " + field);
}
return;
}
boolean required = determineRequiredStatus(ann); // required属性是false or true
currElements.add(new AutowiredFieldElement(field, required)); // 添加到注入列表
}
}
});
// 方法
ReflectionUtils.doWithLocalMethods(targetClass, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); // 有桥接方法的返回桥接方法的最原始方法,否则返回自身(注释中表示这样更加安全的去调用方法,跳过桥接的检测)
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod); // 获取方法上带有注入注解(@Autowired,@value,@inject)并加入AnnotationAttributes列表
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) { // 检测合法性
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterTypes().length == 0) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
boolean required = determineRequiredStatus(ann); // required属性是false or true
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); // 获取目标class中某成员拥有读或写方法与桥接方法一直的PropertyDescriptor
currElements.add(new AutowiredMethodElement(method, required, pd)); // 添加到注入列表
}
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass(); // 有父类继续解析
}while (targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements); // 返回需要注入的信息
}
具体注入的方法:postProcessPropertyValues:
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); // 从缓存中获取InjectionMetadata,未取到则构造注入的metadata
try {
metadata.inject(bean, beanName, pvs); // 具体注入
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
// 注入
public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable {
Collection<InjectedElement> elementsToIterate =
(this.checkedElements != null ? this.checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
boolean debug = logger.isDebugEnabled();
for (InjectedElement element : elementsToIterate) {
if (debug) {
logger.debug("Processing injected element of bean '" + beanName + "': " + element);
}
element.inject(target, beanName, pvs); // 真实注入
}
}
}
// Field注入,method注入
/**
* Either this or {@link #getResourceToInject} needs to be overridden.
*/
protected void inject(Object target, String requestingBeanName, PropertyValues pvs) throws Throwable {
if (this.isField) {
// 注解加在成员上的,注入成员参数
Field field = (Field) this.member;
ReflectionUtils.makeAccessible(field);
field.set(target, getResourceToInject(target, requestingBeanName));
}
else {
if (checkPropertySkipping(pvs)) {
return;
}
try {
// 注解加在方法上的,调用方法注入
Method method = (Method) this.member;
ReflectionUtils.makeAccessible(method);
method.invoke(target, getResourceToInject(target, requestingBeanName));
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
4. 构造函数注入
看到这里可能会产生疑问。@Autowired应该还支持构造方法的注入的啊?仔细想想,AutowiredAnnotationBeanPostProcessor的这两个方法是对非静态field和method的,那对于构造函数来说,其调用一定再这之前(创建bean的时候),而AutowiredAnnotationBeanPostProcessor的determineCandidateConstructors方法为其获取带有注入注解的构造方法(这里不再做解析)。回头看一下创建bean的代码:
createBeanInstance方法中有对构造函数注入的方法,直接看一下源码:
Protected BeanWrapper autowireConstructor(
StringbeanName,RootBeanDefinition mbd,@NullableConstructor<?>[]ctors,@NullableObject[]explicitArgs){
Return new ConstructorResolver(this).autowireConstructor(beanName,mbd,ctors,explicitArgs); // 构造实例化
}