@Autowired原理详解 :标识构造函数

在一个类中定义一个属性,正常情况下需要在此类中有对此属性赋值的代码,如setter方法,或者在构造函数中赋值,因此类和属性之间的关系已经确定下来了,类和属性间就有了一定的耦合关系。而IOC的精髓就是解耦,类中没有显式的对属性的赋值代码,同时属性的实际类型和值在运行时有系统动态的赋值,Spring对IOC做了很大的扩展,使用者可以很灵活的控制注入的对象类型及值。

Spring内IOC的最直接体现就是@Autowired注解,最常用的方式就是表示在属性上,Spring容器在启动时会将容器内类型是标识了@Autowired的属性类型或者其子类,实现类的Bean通过反射的形式赋值给此属性,或者叫注入的此类中。

Spring中对@Autowired注解的解析是通过一个叫AutowiredAnnotationBeanPostProcessor的BeanPostProcessor(Bean的后处理器)来进行的。BeanPostProcessor负责Bean的一系列处理,实例化前后,初始化前后灯阶段执行相应方法,具体方法的执行顺序如下:


BeanPostPrecessors Invoke Procedure(执行流程)

1.InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(Class beanClass, String beanName);

invoke before doCreateBean(),if the method returns not null,the return Object will as the Bean, avoid invoke doCreateBean() ;


2.SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors(Class beanClass, String beanName);

used to determine to use which Constructor to instance Bean;


3.MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName);

the Bean gets instantiated, modify the RootBeanDefinition ,such as adding PropertyValue etc. before populate Bean;


4.SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference(Object bean, String beanName);

invoke before populate Bean,used for resolve Circular Reference;


5.InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(Object bean, String beanName);

invoke in populate Bean, but before fill in values,return false will break the opreation for filling values in Bean;


6.InstantiationAwareBeanPostProcessor.postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName);

invoke in populate Bean, but before fill in values,modify the PropertyValues which will be apply for the Bean,
return null will break the opreation for filling values in Bean;


7.BeanPostProcessor.postProcessBeforeInitialization(Object bean, String beanName);

invoked before invokeInitMethods, modify the finally Bean instance


8.BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName);

invoked after invokeInitMethods, modify the finally Bean instance

使用者可以自己定义自己的BeanPostProcessor,将其以Bean的形式注册到Spring容器中,Spring容器在启动时会执行其相应方法。

AutowiredAnnotationBeanPostProcessor在Spring容器初始化时会最先执行determineCandidateConstructors方法,先看起源码:

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
        implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
        //此方法的含义是解析Bean类里构造函数上的@Autowired注解,如果有合适的标识了@Autowired的构造函数,
        //则在实例化此Bean时会使用此构造函数,@Import和@ComponentScan得到的Bean会如此解析,
        //@Bean标识方法生成的Bean不会如此
        public Constructor[] determineCandidateConstructors(Class beanClass, final String beanName)
            throws BeanCreationException {

        // Let's check for lookup methods here..
        if (!this.lookupMethodsChecked.contains(beanName)) {
            try {
                ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() {
                    @Override
                    public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
                        Lookup lookup = method.getAnnotation(Lookup.class);
                        if (lookup != null) {
                            LookupOverride override = new LookupOverride(method, lookup.value());
                            try {
                                RootBeanDefinition mbd = (RootBeanDefinition) beanFactory.getMergedBeanDefinition(beanName);
                                mbd.getMethodOverrides().addOverride(override);
                            }
                            catch (NoSuchBeanDefinitionException ex) {
                                throw new BeanCreationException(beanName,
                                        "Cannot apply @Lookup to beans without corresponding bean definition");
                            }
                        }
                    }
                });
            }
            catch (IllegalStateException ex) {
                throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
            }
            catch (NoClassDefFoundError err) {
                throw new BeanCreationException(beanName, "Failed to introspect bean class [" + beanClass.getName() +
                        "] for lookup method metadata: could not find class that it depends on", err);
            }
            this.lookupMethodsChecked.add(beanName);
        }

        // Quick check on the concurrent map first, with minimal locking.
        Constructor[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
        if (candidateConstructors == null) {
            // Fully synchronized resolution now...
            synchronized (this.candidateConstructorsCache) {
                //对每个类的构造函数只解析一次,解析完会存储结果,以备下次服用
                candidateConstructors = this.candidateConstructorsCache.get(beanClass);
                if (candidateConstructors == null) {
                    Constructor[] rawCandidates;
                    try {
                        rawCandidates = beanClass.getDeclaredConstructors();
                    }
                    catch (Throwable ex) {
                        throw new BeanCreationException(beanName,
                                "Resolution of declared constructors on bean Class [" + beanClass.getName() +
                                "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
                    }
                    List> candidates = new ArrayList>(rawCandidates.length);
                    Constructor requiredConstructor = null;
                    Constructor defaultConstructor = null;
                    for (Constructor candidate : rawCandidates) {
                        //查看构造函数上是否标识@Autowired注解,获取注解的属性
                        AnnotationAttributes ann = findAutowiredAnnotation(candidate);
                        if (ann == null) {
                            Class userClass = ClassUtils.getUserClass(beanClass);
                            if (userClass != beanClass) {
                                try {
                                    Constructor superCtor =
                                            userClass.getDeclaredConstructor(candidate.getParameterTypes());
                                    //如果此构造函数是重载了父类的构造函数,则寻找父类的构造函数,查看是否标识@Autowired注解,获取注解的属性
                                    ann = findAutowiredAnnotation(superCtor);
                                }
                                catch (NoSuchMethodException ex) {
                                    // Simply proceed, no equivalent superclass constructor found...
                                }
                            }
                        }
                        //当构造函数上存在@Autowired注解
                        if (ann != null) {
                            //@Autowired默认的required = true,当有一个required = true的@Autowired标识的构造函数时,
                            //不能有其他的构造函数再标识@Autowired,否则会报错
                            if (requiredConstructor != null) {
                                throw new BeanCreationException(beanName,
                                        "Invalid autowire-marked constructor: " + candidate +
                                        ". Found constructor with 'required' Autowired annotation already: " +
                                        requiredConstructor);
                            }
                            //@Autowired的required的属性值,true / false
                            boolean required = determineRequiredStatus(ann);
                            if (required) {
                                if (!candidates.isEmpty()) {
                                    throw new BeanCreationException(beanName,
                                            "Invalid autowire-marked constructors: " + candidates +
                                            ". Found constructor with 'required' Autowired annotation: " +
                                            candidate);
                                }
                                requiredConstructor = candidate;
                            }
                            candidates.add(candidate);
                        } 
                        else if (candidate.getParameterTypes().length == 0) {
                            defaultConstructor = candidate;
                        }
                    }
                    if (!candidates.isEmpty()) {
                        // Add default constructor to list of optional constructors, as fallback.
                        当没有构造函数标识@Autowired时,设置默认的构造函数作为额外选择
                        if (requiredConstructor == null) {
                            if (defaultConstructor != null) {
                                candidates.add(defaultConstructor);
                            }  //如果没有默认的无参构造函数,且有@Autowired(required = false)的构造函数,则发出警告信
                            else if (candidates.size() == 1 && logger.isWarnEnabled()) {
                                logger.warn("Inconsistent constructor declaration on bean with name '" + beanName +
                                        "': single autowire-marked constructor flagged as optional - " +
                                        "this constructor is effectively required since there is no " +
                                        "default constructor to fall back to: " + candidates.get(0));
                            }
                        }
                        candidateConstructors = candidates.toArray(new Constructor[candidates.size()]);
                    }  //若只有一个构造函数,且没标识@Autowired,其参数长度>0,将其作为候选者
                    else if (rawCandidates.length == 1 && rawCandidates[0].getParameterTypes().length > 0) {
                        candidateConstructors = new Constructor[] {rawCandidates[0]};
                    } //没有合适的构造函数
                    else {
                        candidateConstructors = new Constructor[0];
                    }
                    this.candidateConstructorsCache.put(beanClass, candidateConstructors);
                }
            }
        }
        return (candidateConstructors.length > 0 ? candidateConstructors : null);
    }

}

AutowiredAnnotationBeanPostProcessor筛选@Autowired标识的构造函数的代码就是这些,筛选出这些构造函数之后,Spring使用ConstructorResolver这个类来择取合适的构造函数,流程如下:

  1. 首先对这些构造函数按修饰符优先public排序,修饰符相同再按参数的长短排序,最先解析参数最长的public修饰的构造函数,其优先级最高.
  2. 对构造函数的每一个参数解析,如果每一个参数均能从Spring容器中找到合适的Bean,则此将此构造函数作为最优解,如果容器内Bean不能满足所有参数,则解析下一个构造函数。
  3. 如果存在两个参数长度相同的构造函数,且容器内Bean均能满足参数解析,则按参数类型和Bean类型的差异性求取参数的差异权重,比如参数是接口,Bean是实现类,则差异加2,参数是集合,Bean是单个类,则转换成集合,差异加2等等,比较两个构造函数的差异权重大小,差异小的那个作为最优解。如果两个差异权重相等,则抛出含有模棱两可的构造函数的BeanCreationException。
  4. 当有了最优解的构造函数后,如果下一个构造函数的参数长度等于最优解,则解析此构造函数,如果参数长度小于最优解,则不再解析,直接忽略之后的所有构造函数。
  5. 当得到了构造函数最优解之后,将此构造函数存入此Bean的BeanDefinition中,以备下次复用,就是说只对构造函数候选者集合解析一次,下次实例化Bean的时候可以直接得到这个最优解。
  6. 以上的情况是基于Spring容器实例化Bean的情况,就是实例化时不会附带Arguments,就是不带参数,如果是使用者自己实例化Bean时,通过BeanFactory的 Object getBean(String name, Object… args) throws BeansException; T getBean(Class requiredType, Object… args) throws BeansException;方法实例化时,按照构造函数的顺序传入实例化参数,则Spring在找合适的构造函数时会忽略之前缓存的最优解,以同样的顺序解析构造函数候选者集合,看看哪些构造函数的参数适合传入的参数,找不到合适的则跑出BeanCreationException。

以上就是@Autowired注解在构造函数上的用法的原理及流程。

重点: BeanFactory的getBean()方法获取scope = singleton的Bean时,不会生成新的Bean对象, 
在scope为request及session的生命周期内,Bean的实例化只会触发一次,也就是说@Autowired的标识的构造函数不是每次调用getBean()均会触发执行。只有scope = prototype的Bean,才会每次均执行。

 

你可能感兴趣的:(@Autowired原理详解 :标识构造函数)