Autowired注解AutowiredAnnotationBeanPostProcessor原理

这篇文章详细描述了一个Spring框架中的AutowiredAnnotationBeanPostProcessor类,该类负责处理@Autowired和@Value等注解的构造方法注入,通过查找带有Lookup注解的方法并检查其构造函数来确保Bean的正确初始化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

class AutowiredAnnotationBeanPostProcessor
        extends InstantiationAwareBeanPostProcessorAdapter
		implements MergedBeanDefinitionPostProcessor{
    // 由此可知,注入的方式可以通过@value,@Inject,@Autowired
    public AutowiredAnnotationBeanPostProcessor() {
        this.autowiredAnnotationTypes.add(Autowired.class);
        this.autowiredAnnotationTypes.add(Value.class);
        this.autowiredAnnotationTypes.add((Class<? extends Annotation>)ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
    }

    @Override
    @Nullable
    public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)throws BeanCreationException {
        // 对Bean进行Lookup注解校验
        if (!this.lookupMethodsChecked.contains(beanName)) {
            if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) {
                Class<?> targetClass = beanClass;
                do {
                    // 找到当前类以及父类的方法中,是否包含Lookup注解
                    ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                        Lookup lookup = method.getAnnotation(Lookup.class);
                        // 如果方法上存在注解,将当前方法进行封装成LookupOverride对象,保存到BD中
                        // 因为有Lookup这个方法对于实例化有影响,需要被代理
                        if (lookup != null) {
                            LookupOverride override = new LookupOverride(method, lookup.value());
                            RootBeanDefinition mbd = (RootBeanDefinition)this.beanFactory.getMergedBeanDefinition(beanName);
                            // 后面会实例化的时候会使用if (!bd.hasMethodOverrides())用到
                            mbd.getMethodOverrides().addOverride(override);
                        }
                    });
                    // 查找父类
                    targetClass = targetClass.getSuperclass();
                }
                // 直到父类为Object
                while (targetClass != null && targetClass != Object.class);
            }
            // 标注当前类已经处理过
            this.lookupMethodsChecked.add(beanName);
        }

        // 当前类的构造方法是否被处理过缓存起来了
        Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
        // 第一次处理没有被缓存
        if (candidateConstructors == null) {
            // 加锁处理
            synchronized (this.candidateConstructorsCache) {
                candidateConstructors = this.candidateConstructorsCache.get(beanClass);
                if (candidateConstructors == null) {
                    // 获取所有的构造方法
                    Constructor<?>[] rawCandidates = beanClass.getDeclaredConstructors();;
                    // 保存候选的构造方法
                    List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
                    // 必须注入的构造方法
                    Constructor<?> requiredConstructor = null;
                    // 默认的构造方法
                    Constructor<?> defaultConstructor = null;
                    // 主要的构造方法,这里只要是处理Kotlin的主构造
                    Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
                    int nonSyntheticConstructors = 0;
                    // 遍历所有的构造方法
                    for (Constructor<?> candidate : rawCandidates) {
                        // 在 Java 中,`Constructor` 类中的 `isSynthetic` 方法用于判断一个构造函数是否是由编译器合成的。
                        // 当一个构造函数是由编译器自动合成而非手动编写时,它就被标记为“合成的”(synthetic)。
                        // 这通常发生在一些特定的情况下,例如内部类的构造函数或者泛型擦除时。
                        // 通过调用 `isSynthetic` 方法,你可以在运行时确定构造函数是由编译器合成的,或者是由程序员手动编写的。
                        // 我们只处理我们自己手动写的构造函数,默认默认的无参构造函数
                        if (!candidate.isSynthetic()) {
                            nonSyntheticConstructors++;
                        }
                        // 如果是合成的构造函数,并且是Kotlin中的主构造,就不往下执行,就使用主构造
                        else if (primaryConstructor != null) {
                            continue;
                        }
                        // 找到构造方法中的注解,注入的三个注解
                        MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
                        // 如果不存在注入的注解
                        if (ann == null) {
                            // 获取用户原始的类,因为可能beanClass为代理类
                            Class<?> userClass = ClassUtils.getUserClass(beanClass);
                            // 如果当前类是代理类
                            if (userClass != beanClass) {
                                // 获取原始类的构造方法
                                Constructor<?> superCtor =userClass.getDeclaredConstructor(candidate.getParameterTypes());
                                // 再次找原始类的注入的注解
                                ann = findAutowiredAnnotation(superCtor);
                            }
                        }
                        // 如果找到了需要注入的注解
                        if (ann != null) {
                            // 第一次进入,requiredConstructor一定是为空的,如果不为空,表示不是第一次处理
                            // 如果上一次已经找到了一个标注了@Autowired(require=true)的构造方法,再发现任何标注了@Autowired的方法
                            // 不管require属性为true,还是false,都会抛出异常
                            // 总结,只要有一个构造标注了@Autowired(require=true),就不能存在任何其他的@Autowired的构造
                            // 哪怕是@Autowired(required=false)都不行
                            if (requiredConstructor != null) {
                                throw new BeanCreationException(beanName,
                                        "Invalid autowire-marked constructor: " + candidate +
                                        ". Found constructor with 'required' Autowired annotation already: " +
                                        requiredConstructor);
                            }
                            // 到这,表示暂时没有需要强制注入的构造方法
                            boolean required = determineRequiredStatus(ann);
                            // 获取是否必须要注入标识
                            if (required) {
                                // 第一次进入,candidates一定是为空的,如果不为空,表示不是第一次处理
                                // 当不是第一次处理,上一次处理已经将标注了@Autowire的构造函数保存到candidates了,所以candidates不为空
                                // 而能进入这个判断,表示当前遍历的构造方法是必须要注入的
                                // 此时,之前的保存构造中,@Autowired的require的属性不论为true,还是false,都会抛出异常
                                // 总结,只要有一个构造标注了@Autowired(require=true),就不能存在任何其他的@Autowired的构造
                                // 哪怕是@Autowired(required=false)都不行
                                // 这里和上面if (requiredConstructor != null)逻辑差不多,取决于先遍历哪一个构造方法
                                if (!candidates.isEmpty()) {
                                    throw new BeanCreationException(beanName,
                                            "Invalid autowire-marked constructors: " + candidates +
                                            ". Found constructor with 'required' Autowired annotation: " +
                                            candidate);
                                }
                                // 将当前遍历的构造函数赋值给requiredConstructor
                                requiredConstructor = candidate;
                            }
                            // 保存为候选的构造函数
                            candidates.add(candidate);
                        }
                        // 如果构造方法没有参数,那就是默认的构造方法了
                        else if (candidate.getParameterCount() == 0) {
                            defaultConstructor = candidate;
                        }
                    }
                    // 找到了候选的构造方法
                    // 表示找到了标注了@Autowired注解的构造方法
                    if (!candidates.isEmpty()) {
                        // 如果没有require=true的注解.也就是没有强制要求使用构造注入的方法
                        if (requiredConstructor == null) {
                            // 将默认的构造方法也作为候选的构造方法
                            if (defaultConstructor != null) {
                                candidates.add(defaultConstructor);
                            }
                        }
                        // 保存所有的候选的构造方法
                        candidateConstructors = candidates.toArray(new Constructor<?>[0]);
                    }
                    // 如果没有找到候选的构造方法,也就是没有标注了Autowired注解

                    // 当只有一个构造方法,并且还有有参数的,那这个唯一的有参也就是候选的
                    else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
                        candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
                    }
                    // 存在两个手写的构造方法,并且有一个默认的,还有一个kotlin中的主构造的情况下
                    // 那么,默认的和主构造都可以作为候选的构造
                    else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
                            defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
                        candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
                    }
                    // 如果只有一个手写的构造方法,并且这个构造是kotlin的主构造
                    // 将主构造作为候选的
                    else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
                        candidateConstructors = new Constructor<?>[] {primaryConstructor};
                    }
                    // 其他情况,没有候选的构造方法
                    else {
                        candidateConstructors = new Constructor<?>[0];
                    }
                    this.candidateConstructorsCache.put(beanClass, candidateConstructors);
                }
            }
        }
        // 返回候选的构造方法
        return (candidateConstructors.length > 0 ? candidateConstructors : null);
    }

    // 这个先缓存字段需要注入的原信息
    @Override
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);{
            // 生成缓存Key
            String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
            // 看一下是否被缓存过注入的元数据
            InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
            // 是否需要刷新元数据,默认是要刷新的
            // 因为第一次进入,metadata没有被缓存,所以都是为空的
            if (InjectionMetadata.needsRefresh(metadata, clazz){
                                        return (metadata == null || metadata.targetClass != clazz);
                                    }) {
                // 加锁处理
                synchronized (this.injectionMetadataCache) {
                    // 再次校验有没有缓存过元数据
                    metadata = this.injectionMetadataCache.get(cacheKey);
                    if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                        // 如果存在元数据,清空,重新处理,因为可能并发处理了
                        if (metadata != null) {
                            // 清空之前处理的值
                            metadata.clear(pvs);
                        }
                        // 创建注入的元数据
                        metadata = buildAutowiringMetadata(clazz);{
                            // 确定当前类需要被注入,存在注入的注解
                            if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
                                return InjectionMetadata.EMPTY;
                            }
                            // 保存所有需要注入的信息
                            List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
                            Class<?> targetClass = clazz;
                            do {
                                final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
                                // 找到当前注入类的所有字段,字段注入
                                ReflectionUtils.doWithLocalFields(targetClass, field -> {
                                    // 找到注入的注解类型
                                    MergedAnnotation<?> ann = findAutowiredAnnotation(field);
                                    // 如果字段上标注了注入的注解
                                    if (ann != null) {
                                        // 如果是静态,不处理
                                        if (Modifier.isStatic(field.getModifiers())) {
                                            if (logger.isInfoEnabled()) {
                                                logger.info("Autowired annotation is not supported on static fields: " + field);
                                            }
                                            return;
                                        }
                                        // 是否必须注入
                                        boolean required = determineRequiredStatus(ann);
                                        // 将字段封装成AutowiredFieldElement对象,保存字段信息和是否必须
                                        currElements.add(new AutowiredFieldElement(field, required));
                                    }
                                });
                                // 找到所有的方法,方法注入
                                // 和字段注入基本一样
                                ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                                    Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
                                    if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                                        return;
                                    }
                                    MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
                                    // 不处理静态的
                                    if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                                        if (Modifier.isStatic(method.getModifiers())) {
                                            if (logger.isInfoEnabled()) {
                                                logger.info("Autowired annotation is not supported on static methods: " + method);
                                            }
                                            return;
                                        }
                                        boolean required = determineRequiredStatus(ann);
                                        // PropertyDescriptor是对JavaBean属性的抽象访问
                                        PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                                        // 将方法封装成AutowiredMethodElement对象,保存方法信息和是否必须,以及对方法的抽象访问
                                        currElements.add(new AutowiredMethodElement(method, required, pd));
                                    }
                                });
                                // 保存所有的字段注入和方法注入信息
                                elements.addAll(0, currElements);
                                // 继续扫描父类
                                targetClass = targetClass.getSuperclass();
                            }
                            while (targetClass != null && targetClass != Object.class);
                            // 将当前类中字段注入和方法注入的信息封装成InjectionMetadata注入元信息
                            return InjectionMetadata.forElements(elements, clazz);
                        }
                        // 缓存字段注入的元信息
                        this.injectionMetadataCache.put(cacheKey, metadata);
                    }
                }
            }
            return metadata;
        }
        // 校验成员是不已经被管理了
        metadata.checkConfigMembers(beanDefinition);{
            Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
            // 遍历所有注入的元素信息
            for (InjectedElement element : this.injectedElements) {
                // 获取成员信息,Member是Method,Field的抽象
                Member member = element.getMember();
                // 判断member是不是由Spring管理和调用,默认返回false,表示不是Spring管理的
                // 那么就需要交给Spring进行管理
                if (!beanDefinition.isExternallyManagedConfigMember(member)) {
                    // 将成员交给Spring管理和调用
                    beanDefinition.registerExternallyManagedConfigMember(member);
                    // 保存被校验了的元素
                    checkedElements.add(element);
                }
            }
            // 这个保存的是所有没有被外部管理的配置成员的元素信息
            // 如果被外部成员管理,beanDefinition.isExternallyManagedConfigMember(member)就为true,表示已经被管理了
            // 就不需要再次管理,只需要管理一次
            this.checkedElements = checkedElements;
        }
    }

    // 处理属性
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        // 找到注入的原信息,在postProcessMergedBeanDefinition的时候就已经缓存了
        InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
        // 依赖注入
        metadata.inject(bean, beanName, pvs);{
            // 具体了可以看postProcessMergedBeanDefinition方法,因为都是在postProcessMergedBeanDefinition提前完成了操作
            Collection<InjectedElement> checkedElements = this.checkedElements;
            Collection<InjectedElement> elementsToIterate = (checkedElements != null ? checkedElements : this.injectedElements);
            // 如果存在需要注入的信息
            if (!elementsToIterate.isEmpty()) {
                // 遍历所有的元素
                for (InjectedElement element : elementsToIterate) {
                    // 注入
                    element.inject(target, beanName, pvs);{
                        Field field = (Field) this.member;
                        // 类型转换器
                        TypeConverter typeConverter = beanFactory.getTypeConverter();
                        // 获取转换后的Bean,如果有需要转换,并将beanName保存到autowiredBeanNames中
                        value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
                        // 保存Bean的依赖关系
                        registerDependentBeans(beanName, autowiredBeanNames);{
                            if (beanName != null) {
                                // 遍历上面解析的beanName
                                for (String autowiredBeanName : autowiredBeanNames) {
                                    // beanName在工厂中存在
                                    if (this.beanFactory != null && this.beanFactory.containsBean(autowiredBeanName)) {
                                        // 保存Bean的依赖关系
                                        this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
                                    }
                                }
                            }
                        }
                        if (value != null) {
                            // 反射设置
                            ReflectionUtils.makeAccessible(field);
                            field.set(bean, value);
                        }
                    }
                }
            }
        }
        return pvs;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值