• Autowired如何实现自动注入?


    @Autowired注解的实现过程,其实就是Spring Bean的自动装配过程。通过看@Autowired源码注释部分我们可以看到@Autowired的实现是通过AutowiredAnnotationBeanPostProcessor后置处理器中实现的。

    AutowiredAnnotationBeanPostProcessor 类的关系

    • PriorityOrdered:确认 AutowiredAnnotationBeanPostProcessor 后置处理器的执行优先级
    • BeanFactoryAware:使得AutowiredAnnotationBeanPostProcessor可以直接通过BeanFactory获取容器中的Bean
    • BeanPostProcessor:在 Bean 初始化前后执行的后置处理器
    • InstantiationAwareBeanPostProcessor:在 Bean 实例化前后和Bean设置属性值时执行的后置处理器
    • SmartInstantiationAwareBeanPostProcessor:智能实例化Bean的后处理器,如预测Bean的类型和确认Bean的构造函数等。
    • MergedBeanDefinitionPostProcessor:合并Bean的定义信息。

    在分析自动装配前我们先来介绍一下上面的这些后置处理器。

    后置处理器介绍

    BeanPostProcessor

    BeanPostProcessor有两个方法,postProcessBeforeInitializationpostProcessAfterInitialization。它们分别在任何bean初始化回调之前或之后执行(例如InitializingBean的afterPropertiesSet方法或自定义init-method方法之前或者之后), 在这个时候该bean的属性值已经填充完成了,并且我们返回的bean实例可能已经是原始实例的包装类型了。例如返回一个FactoryBean

    InstantiationAwareBeanPostProcessor

    InstantiationAwareBeanPostProcessor继承自BeanPostProcessor接口。主要多提供了以下三个方法。

    postProcessBeforeInstantiation

    该方法是在Bean实例化目标对象之前调用,返回的Bean对象可以代理目标,从而有效的阻止了目标Bean的默认实例化。

    1. protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    2. Object bean = null;
    3. if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
    4. // Make sure bean class is actually resolved at this point.
    5. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    6. Class targetType = determineTargetType(beanName, mbd);
    7. if (targetType != null) {
    8. bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
    9. if (bean != null) {
    10. // 如果此方法返回一个非null对象,则Bean创建过程将被短路。
    11. // 唯一应用的进一步处理是来自已配置BeanPostProcessors的postProcessAfterInitialization回调
    12. bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
    13. }
    14. }
    15. }
    16. mbd.beforeInstantiationResolved = (bean != null);
    17. }
    18. return bean;
    19. }
    20. protected Object applyBeanPostProcessorsBeforeInstantiation(Class beanClass, String beanName) {
    21. for (BeanPostProcessor bp : getBeanPostProcessors()) {
    22. if (bp instanceof InstantiationAwareBeanPostProcessor) {
    23. InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    24. // 执行Bean实例化目标对象之前的后置处理方法
    25. Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
    26. if (result != null) {
    27. return result;
    28. }
    29. }
    30. }
    31. return null;
    32. }

    跟进源码我们可以看出,如果此方法返回一个非null对象,则Bean创建过程将被短路。唯一应用的进一步处理是来自已配置BeanPostProcessors的postProcessAfterInitialization回调。

    自动装配的实现

    找到需要自动装配的元素

    AutowiredAnnotationBeanPostProcessor后置处理器主要负责对添加了@Autowired和@Value注解的元素实现自动装配。所以找到需要自动装配的元素,其实就是对@Autowired和@Value注解的解析。

    AutowiredAnnotationBeanPostProcessor后置处理器,找出需要自动装配的元素是在MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition这个方法中实现的;

    1. doWith:445, AutowiredAnnotationBeanPostProcessor$2 (org.springframework.beans.factory.annotation)
    2. doWithLocalFields:657, ReflectionUtils (org.springframework.util)
    3. buildAutowiringMetadata:433, AutowiredAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation)
    4. findAutowiringMetadata:412, AutowiredAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation)
    5. postProcessMergedBeanDefinition:235, AutowiredAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation)
    6. applyMergedBeanDefinitionPostProcessors:1000, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
    7. doCreateBean:523, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
    8. createBean:483, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
    9. getObject:312, AbstractBeanFactory$1 (org.springframework.beans.factory.support)
    10. getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
    11. doGetBean:308, AbstractBeanFactory (org.springframework.beans.factory.support)
    12. getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support)
    13. preInstantiateSingletons:761, DefaultListableBeanFactory (org.springframework.beans.factory.support)
    14. finishBeanFactoryInitialization:867, AbstractApplicationContext (org.springframework.context.support)
    15. refresh:543, AbstractApplicationContext (org.springframework.context.support)
    16. :84, AnnotationConfigApplicationContext (org.springframework.context.annotation)

    从链路上我们可以看到,找到需要自动装配的元素是在findAutowiringMetadata方法中实现的,该方法会去调用buildAutowiringMetadata方法构建元数据信息。如果注解被加载属性上将会被封装成AutowiredFieldElement对象;如果注解加在方法上,那么元素会被封装成AutowiredMethodElement对象。这里两个对象的inject方法将最后完成属性值的注入,主要区别就是使用反射注入值的方式不一样。源码如下:

    1. private InjectionMetadata buildAutowiringMetadata(final Class clazz) {
    2. LinkedList elements = new LinkedList();
    3. Class targetClass = clazz;
    4. do {
    5. // 存放我们找到的元数据信息
    6. final LinkedList currElements =
    7. new LinkedList();
    8. // 通过反射找出对应Class对象的所有Field
    9. ReflectionUtils.doWithLocalFields(targetClass, new ReflectionUtils.FieldCallback() {
    10. @Override
    11. public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
    12. // 通过反射找到该字段上所有的注解信息,并判断是否有@Autowired和@Value注解,如果有就将该字段封成AutowiredFieldElement对象
    13. AnnotationAttributes ann = findAutowiredAnnotation(field);
    14. if (ann != null) {
    15. if (Modifier.isStatic(field.getModifiers())) {
    16. if (logger.isWarnEnabled()) {
    17. logger.warn("Autowired annotation is not supported on static fields: " + field);
    18. }
    19. return;
    20. }
    21. boolean required = determineRequiredStatus(ann);、
    22. // 将该字段封成AutowiredFieldElement对象,并放到缓存中
    23. currElements.add(new AutowiredFieldElement(field, required));
    24. }
    25. }
    26. });
    27. // 通过反射找出对应Class对象的所有Method
    28. ReflectionUtils.doWithLocalMethods(targetClass, new ReflectionUtils.MethodCallback() {
    29. @Override
    30. public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
    31. Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
    32. if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
    33. return;
    34. }
    35. // 通过反射找到该字段上所有的注解信息,并判断是否有@Autowired和@Value注解,如果有就将该字段封成AutowiredMethodElement对象
    36. AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
    37. if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
    38. if (Modifier.isStatic(method.getModifiers())) {
    39. if (logger.isWarnEnabled()) {
    40. logger.warn("Autowired annotation is not supported on static methods: " + method);
    41. }
    42. return;
    43. }
    44. if (method.getParameterTypes().length == 0) {
    45. if (logger.isWarnEnabled()) {
    46. logger.warn("Autowired annotation should only be used on methods with parameters: " +
    47. method);
    48. }
    49. }
    50. boolean required = determineRequiredStatus(ann);
    51. PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
    52. // 将该字段封成AutowiredMethodElement对象
    53. currElements.add(new AutowiredMethodElement(method, required, pd));
    54. }
    55. }
    56. });
    57. elements.addAll(0, currElements);
    58. targetClass = targetClass.getSuperclass();
    59. }
    60. // 循环处理父类需要自动装配的元素
    61. while (targetClass != null && targetClass != Object.class);
    62. // 将需要自动装配的元素封装成InjectionMetadata对象,最后合并到Bean定义中
    63. return new InjectionMetadata(clazz, elements);
    64. }
  • 相关阅读:
    【初始C语言】/*C语言初阶指针通俗详解*/
    Spring Boot Security 角色授权示例
    Redis 双写一致原理篇
    深信服安全GPT 2.0升级,开启安全运营“智能驾驶”旅程
    【初阶数据结构】——堆的引入
    532.数组中的k-diff数对 Python&Java 哈希表、双指针双解
    基于JAVA+SpringMVC+Mybatis+MYSQL的在线论坛管理系统
    4.9每日一题(多元抽象复合函数求二阶偏导)
    骨干全光网技术发展趋势探讨
    【无标题】
  • 原文地址:https://blog.csdn.net/qq_51956240/article/details/127499298