AutowiredAnnotationBeanPostProcessor

AutowiredAnnotationBeanPostProcessor实现,自动装配带注释的字段,setter方法和任意配置方法

要注入的这些成员是通过Java 5注释检测的:默认情况下,Spring的@Autowired和@Value注释。
还支持JSR-330的@Inject注释(如果可用),作为Spring自己的@Autowired的直接替代品。

任何给定bean类中只有一个构造函数(最大值)可以携带此注释,并将'required'参数设置为true,表示构造函数在用作Spring bean时要自动装配。如果多个非必需构造函数带有注释,则它们将被视为自动装配的候选者。将选择具有最大数量依赖关系的构造函数,这些构造函数可以通过匹配Spring容器中的bean来满足。如果不能满足任何候选者,则将使用默认构造函数(如果存在)。带注释的构造函数不必是公共的。

在调用任何配置方法之前,在构造bean之后立即注入字段。这样的配置字段不必是公共的。

配置方法可以有任意名称和任意数量的参数;每个参数都将使用Spring容器中的匹配bean进行自动装配。 Bean属性setter方法实际上只是这种通用配置方法的一个特例。配置方法不必是公开的。

注意:默认的AutowiredAnnotationBeanPostProcessor将由“context:annotation-config”和“context:component-scan”XML标记注册。如果要指定自定义AutowiredAnnotationBeanPostProcessor bean定义,请删除或关闭默认注释配置。

注意:注释注入将在XML注入之前执行;因此后一种配置将覆盖通过两种方法连接的属性的前者。

除了上面讨论的常规注入点之外,这个后处理器还处理Spring的@Lookup注释,该注释标识了在运行时由容器替换的查找方法。

 

AutowiredAnnotationBeanPostProcessor里面包含3个内部类AutowiredFieldElement和AutowiredMethodElement和

ShortcutDependencyDescriptor,而AutowiredFieldElement和AutowiredMethodElement分别处理字段和方法的注解。

注入()方法被调用是在AutowiredAnnotationBeanPostProcessor的postProcessPropertyValues方法上

内部类:AutowiredFieldElement

private class AutowiredFieldElement extends InjectedElement {
        private final boolean required;
        private volatile boolean cached = false;
        private volatile Object cachedFieldValue;

        public AutowiredFieldElement(Field field, boolean required) {
            super(field, (PropertyDescriptor)null);
            this.required = required;
        }

        protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {

            //InjectedElem的属性之一,Member是一个接口java.lang.reflect
            //class Field extends AccessibleObject implements Member
            Field field = (Field)this.member;
            Object value;
            if (this.cached) {
                value = AutowiredAnnotationBeanPostProcessor.this.resolvedCachedArgument(beanName, this.cachedFieldValue);
            } else {
                DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
                desc.setContainingClass(bean.getClass());
                Set<String> autowiredBeanNames = new LinkedHashSet(1);
                TypeConverter typeConverter = AutowiredAnnotationBeanPostProcessor.this.beanFactory.getTypeConverter();

                try {
                    //通过BeanFactory的resolveDependency()方法解决依赖的值。也就是这个参数需要注入的值
                    value = AutowiredAnnotationBeanPostProcessor.this.beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
                } catch (BeansException var12) {
                    throw new UnsatisfiedDependencyException((String)null, beanName, new InjectionPoint(field), var12);
                }

                synchronized(this) {
                    if (!this.cached) {//没有缓存
                        if (value == null && !this.required) {
                            this.cachedFieldValue = null;
                        } else {
                            this.cachedFieldValue = desc;
                            AutowiredAnnotationBeanPostProcessor.this.registerDependentBeans(beanName, autowiredBeanNames);//依赖注入
                            if (autowiredBeanNames.size() == 1) {
                                String autowiredBeanName = (String)autowiredBeanNames.iterator().next();
//对字段类型进行匹配
                                if (AutowiredAnnotationBeanPostProcessor.this.beanFactory.containsBean(autowiredBeanName) && AutowiredAnnotationBeanPostProcessor.this.beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
                                    this.cachedFieldValue = new AutowiredAnnotationBeanPostProcessor.ShortcutDependencyDescriptor(desc, autowiredBeanName, field.getType());
                                }
                            }
                        }

                        this.cached = true;
                    }
                }
            }

            if (value != null) {
                //这里就是通过反射设置参数可见性,然后把值设置到该参数上
                ReflectionUtils.makeAccessible(field);
                field.set(bean, value);
            }

        }
    }

AutowiredAnnotationBeanPostProcessor类的其他内容

 


   private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet();
    private String requiredParameterName = "required";
    private boolean requiredParameterValue = true;
    private int order = 2147483645;
    private ConfigurableListableBeanFactory beanFactory;
    private final Set<String> lookupMethodsChecked = Collections.newSetFromMap(new ConcurrentHashMap(256));
    private final Map<Class<?>, Constructor<?>[]> candidateConstructorsCache = new ConcurrentHashMap(256);
    private final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap(256);

    //把注解加进set集合中
    public AutowiredAnnotationBeanPostProcessor() {
        this.autowiredAnnotationTypes.add(Autowired.class);
        this.autowiredAnnotationTypes.add(Value.class);

        try {
            this.autowiredAnnotationTypes.add(ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
            this.logger.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
        } catch (ClassNotFoundException var2) {
        }

    }
    //先清空在重新装进set
    public void setAutowiredAnnotationType(Class<? extends Annotation> autowiredAnnotationType) {
        Assert.notNull(autowiredAnnotationType, "'autowiredAnnotationType' must not be null");
        this.autowiredAnnotationTypes.clear();
        this.autowiredAnnotationTypes.add(autowiredAnnotationType);
    }

    public void setAutowiredAnnotationTypes(Set<Class<? extends Annotation>> autowiredAnnotationTypes) {
        Assert.notEmpty(autowiredAnnotationTypes, "'autowiredAnnotationTypes' must not be empty");
        this.autowiredAnnotationTypes.clear();
        this.autowiredAnnotationTypes.addAll(autowiredAnnotationTypes);
    }

    public void setRequiredParameterName(String requiredParameterName) {
        this.requiredParameterName = requiredParameterName;
    }

    public void setRequiredParameterValue(boolean requiredParameterValue) {
        this.requiredParameterValue = requiredParameterValue;
    }

    public void setOrder(int order) {
        this.order = order;
    }

    public int getOrder() {
        return this.order;
    }
       //设置beanfactory
    public void setBeanFactory(BeanFactory beanFactory) {
        if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
            throw new IllegalArgumentException("AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory: " + beanFactory);
        } else {
            this.beanFactory = (ConfigurableListableBeanFactory)beanFactory;
        }
    }

    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        if (beanType != null) {
            InjectionMetadata metadata = this.findAutowiringMetadata(beanName, beanType, (PropertyValues)null);
            metadata.checkConfigMembers(beanDefinition);
        }

    }

    public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName) throws BeanCreationException {
        if (!this.lookupMethodsChecked.contains(beanName)) {
            try {
                ReflectionUtils.doWithMethods(beanClass, new MethodCallback() {
                    public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
                        Lookup lookup = (Lookup)method.getAnnotation(Lookup.class);
                        if (lookup != null) {
                            LookupOverride override = new LookupOverride(method, lookup.value());

                            try {
                                RootBeanDefinition mbd = (RootBeanDefinition)AutowiredAnnotationBeanPostProcessor.this.beanFactory.getMergedBeanDefinition(beanName);
                                mbd.getMethodOverrides().addOverride(override);
                            } catch (NoSuchBeanDefinitionException var5) {
                                throw new BeanCreationException(beanName, "Cannot apply @Lookup to beans without corresponding bean definition");
                            }
                        }

                    }
                });
            } catch (IllegalStateException var19) {
                throw new BeanCreationException(beanName, "Lookup method resolution failed", var19);
            } catch (NoClassDefFoundError var20) {
                throw new BeanCreationException(beanName, "Failed to introspect bean class [" + beanClass.getName() + "] for lookup method metadata: could not find class that it depends on", var20);
            }

            this.lookupMethodsChecked.add(beanName);
        }

        Constructor<?>[] candidateConstructors = (Constructor[])this.candidateConstructorsCache.get(beanClass);
        if (candidateConstructors == null) {
            synchronized(this.candidateConstructorsCache) {
                candidateConstructors = (Constructor[])this.candidateConstructorsCache.get(beanClass);
                if (candidateConstructors == null) {
                    Constructor[] rawCandidates;
                    try {
                        rawCandidates = beanClass.getDeclaredConstructors();
                    } catch (Throwable var18) {
                        throw new BeanCreationException(beanName, "Resolution of declared constructors on bean Class [" + beanClass.getName() + "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", var18);
                    }

                    List<Constructor<?>> candidates = new ArrayList(rawCandidates.length);
                    Constructor<?> requiredConstructor = null;
                    Constructor<?> defaultConstructor = null;
                    Constructor[] var9 = rawCandidates;
                    int var10 = rawCandidates.length;

                    for(int var11 = 0; var11 < var10; ++var11) {
                        Constructor<?> candidate = var9[var11];
                        AnnotationAttributes ann = this.findAutowiredAnnotation(candidate);
                        if (ann == null) {
                            Class<?> userClass = ClassUtils.getUserClass(beanClass);
                            if (userClass != beanClass) {
                                try {
                                    Constructor<?> superCtor = userClass.getDeclaredConstructor(candidate.getParameterTypes());
                                    ann = this.findAutowiredAnnotation(superCtor);
                                } catch (NoSuchMethodException var17) {
                                }
                            }
                        }

                        if (ann != null) {
                            if (requiredConstructor != null) {
                                throw new BeanCreationException(beanName, "Invalid autowire-marked constructor: " + candidate + ". Found constructor with 'required' Autowired annotation already: " + requiredConstructor);
                            }

                            boolean required = this.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()) {
                        if (requiredConstructor == null) {
                            if (defaultConstructor != null) {
                                candidates.add(defaultConstructor);
                            } else if (candidates.size() == 1 && this.logger.isWarnEnabled()) {
                                this.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 = (Constructor[])candidates.toArray(new Constructor[candidates.size()]);
                    } 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;
    }

    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
        InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs);

        try {
            metadata.inject(bean, beanName, pvs);
            return pvs;
        } catch (BeanCreationException var7) {
            throw var7;
        } catch (Throwable var8) {
            throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var8);
        }
    }

    public void processInjection(Object bean) throws BeanCreationException {
        Class<?> clazz = bean.getClass();
        InjectionMetadata metadata = this.findAutowiringMetadata(clazz.getName(), clazz, (PropertyValues)null);

        try {
            metadata.inject(bean, (String)null, (PropertyValues)null);
        } catch (BeanCreationException var5) {
            throw var5;
        } catch (Throwable var6) {
            throw new BeanCreationException("Injection of autowired dependencies failed for class [" + clazz + "]", var6);
        }
    }

    private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
        String cacheKey = StringUtils.hasLength(beanName) ? beanName : clazz.getName();
        InjectionMetadata metadata = (InjectionMetadata)this.injectionMetadataCache.get(cacheKey);
        if (InjectionMetadata.needsRefresh(metadata, clazz)) {
            synchronized(this.injectionMetadataCache) {
                metadata = (InjectionMetadata)this.injectionMetadataCache.get(cacheKey);
                if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                    if (metadata != null) {
                        metadata.clear(pvs);
                    }

                    try {
                        metadata = this.buildAutowiringMetadata(clazz);
                        this.injectionMetadataCache.put(cacheKey, metadata);
                    } catch (NoClassDefFoundError var9) {
                        throw new IllegalStateException("Failed to introspect bean class [" + clazz.getName() + "] for autowiring metadata: could not find class that it depends on", var9);
                    }
                }
            }
        }

        return metadata;
    }
  
    private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
        LinkedList<InjectedElement> elements = new LinkedList();
        Class targetClass = clazz;

        do {
            final LinkedList<InjectedElement> currElements = new LinkedList();
            ReflectionUtils.doWithLocalFields(targetClass, new FieldCallback() {
                public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
//调用findAutowiredAnnotation 找到需要注入的属性,然后在装配
                    AnnotationAttributes ann = AutowiredAnnotationBeanPostProcessor.this.findAutowiredAnnotation(field);
                    if (ann != null) {
                        if (Modifier.isStatic(field.getModifiers())) {
                            if (AutowiredAnnotationBeanPostProcessor.this.logger.isWarnEnabled()) {
                                AutowiredAnnotationBeanPostProcessor.this.logger.warn("Autowired annotation is not supported on static fields: " + field);
                            }

                            return;
                        }

                        boolean required = AutowiredAnnotationBeanPostProcessor.this.determineRequiredStatus(ann);
                        currElements.add(AutowiredAnnotationBeanPostProcessor.this.new AutowiredFieldElement(field, required));
                    }

                }
            });
            ReflectionUtils.doWithLocalMethods(targetClass, new MethodCallback() {
                public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
                    Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
                    if (BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                        AnnotationAttributes ann = AutowiredAnnotationBeanPostProcessor.this.findAutowiredAnnotation(bridgedMethod);
                        if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                            if (Modifier.isStatic(method.getModifiers())) {
                                if (AutowiredAnnotationBeanPostProcessor.this.logger.isWarnEnabled()) {
                                    AutowiredAnnotationBeanPostProcessor.this.logger.warn("Autowired annotation is not supported on static methods: " + method);
                                }

                                return;
                            }

                            if (method.getParameterTypes().length == 0 && AutowiredAnnotationBeanPostProcessor.this.logger.isWarnEnabled()) {
                                AutowiredAnnotationBeanPostProcessor.this.logger.warn("Autowired annotation should only be used on methods with parameters: " + method);
                            }

                            boolean required = AutowiredAnnotationBeanPostProcessor.this.determineRequiredStatus(ann);
                            PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                            currElements.add(AutowiredAnnotationBeanPostProcessor.this.new AutowiredMethodElement(method, required, pd));
                        }

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

        return new InjectionMetadata(clazz, elements);
    }

    private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
        if (ao.getAnnotations().length > 0) {
            Iterator var2 = this.autowiredAnnotationTypes.iterator();

            while(var2.hasNext()) {
                Class<? extends Annotation> type = (Class)var2.next();
                AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type);
                if (attributes != null) {
                    return attributes;
                }
            }
        }

        return null;
    }

    protected boolean determineRequiredStatus(AnnotationAttributes ann) {
        return !ann.containsKey(this.requiredParameterName) || this.requiredParameterValue == ann.getBoolean(this.requiredParameterName);
    }

    protected <T> Map<String, T> findAutowireCandidates(Class<T> type) throws BeansException {
        if (this.beanFactory == null) {
            throw new IllegalStateException("No BeanFactory configured - override the getBeanOfType method or specify the 'beanFactory' property");
        } else {
            return BeanFactoryUtils.beansOfTypeIncludingAncestors(this.beanFactory, type);
        }
    }
        //向autowiredBeanNames注入beanname的bean对象
    private void registerDependentBeans(String beanName, Set<String> autowiredBeanNames) {
        if (beanName != null) {
            Iterator var3 = autowiredBeanNames.iterator();

            while(var3.hasNext()) {
                String autowiredBeanName = (String)var3.next();
                if (this.beanFactory.containsBean(autowiredBeanName)) {
                    this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
                }

                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Autowiring by type from bean name '" + beanName + "' to bean named '" + autowiredBeanName + "'");
                }
            }
        }

    }

    private Object resolvedCachedArgument(String beanName, Object cachedArgument) {
        if (cachedArgument instanceof DependencyDescriptor) {
            DependencyDescriptor descriptor = (DependencyDescriptor)cachedArgument;
            return this.beanFactory.resolveDependency(descriptor, beanName, (Set)null, (TypeConverter)null);
        } else {
            return cachedArgument;
        }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值