<导航

Spring注入 @Autowired和setter方式区别原理

pring 的注入方式有:setter、constructor、静态工厂方法、实例工厂方法、注解@Autowired自动装配几种方式。

今天我们要了解的是:setter和@Autowired两种方式的区别,常用的setter方式很好理解,通过调用Bean的属性setter方法直观的赋值即可。而@Autowired方式,没有setter方法赋值又是通过什么方式实现的呢?看一下spring源码:

1、AbstractAutowireCapableBeanFactory类中的autowireBean()方法

populateBean()方法:

2、AutowiredAnnotationBeanPostProcessor类中通过postProcessPropertyValues()方法很容易找到内部类AutowiredFieldElement.inject()方法:

通过上面的代码很容易了解到,@Autowired方式是通过反射来设置属性值的,噢。。。。。。。。。万能而无节操的反射,明白了吧


@Autowired注解使用及原理

required属性

  required属性值可以为true( 默认值)和false。如果为true的话,没有匹配的类则抛出异常;如果为false,则表示不是强制必须能够找到相应的类,无论是否注入成功,都不会抛错。

工作原理
 注解解析器:AutowiredAnnotationBeanPostProcessor

Spring容器启动时,AutowiredAnnotationBeanPostProcessor被注册到容器;
扫描代码,如果带有@Autowired注解,则将依赖注入信息封装到InjectionMetadata中(见扫描过程);
创建bean时(实例化对象和初始化),会调用各种BeanPostProcessor对bean初始化,AutowiredAnnotationBeanPostProcessor负责将相关的依赖注入进来;

Spring 创建对象分为三个过程:

1、创建对象实例 Object obj = new Object() 或者 Object obj = new Object(xxx);
  AbstractAutowireCapableBeanFactory#createBeanInstance
2、依赖注入: obj.setXxx(xxx) {多个属性就是 foreach}
  AbstractAutowireCapableBeanFactory#populateBean
3、Spring bean 扩展方法:init-method,BeanPostProcess,XXXAware 扩展
  AbstractAutowireCapableBeanFactory#initializeBean

@Autowired扫描过程

  1. 扫描当前类中标注@Autowired的属性和方法;
  2. 再查找父类中注@Autowired的属性和方法,依次遍历;
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
        LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<>();
        Class<?> targetClass = clazz;

        do {
            final LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<>();

            ReflectionUtils.doWithLocalFields(targetClass, field -> {
                AnnotationAttributes ann = findAutowiredAnnotation(field);
                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);
                    currElements.add(new AutowiredFieldElement(field, required));
                }
            });

            ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
                if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                    return;
                }
                AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
                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.getParameterCount() == 0) {
                        if (logger.isWarnEnabled()) {
                            logger.warn("Autowired annotation should only be used on methods with parameters: " +
                                    method);
                        }
                    }
                    boolean required = determineRequiredStatus(ann);
                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                    currElements.add(new AutowiredMethodElement(method, required, pd));
                }
            });

            elements.addAll(0, currElements);
            targetClass = targetClass.getSuperclass();
        }while (targetClass != null && targetClass != Object.class);
View Code

 

 

 

 

参考文章:

https://blog.csdn.net/wenluoxicheng/article/details/73608657

https://blog.csdn.net/yangguosb/article/details/84594129

https://juejin.im/entry/5ad3fda5f265da238d512a98

posted @ 2019-09-25 15:03  字节悦动  阅读(3816)  评论(0编辑  收藏  举报