Resource注解CommonAnnotationBeanPostProcessor原理

文章详细描述了CommonAnnotationBeanPostProcessor如何处理@WebServiceRef,@EJB,@Resource注解,以及如何管理@PostConstruct和@PreDestroy生命周期方法,以及对@Resource的字段和方法注入过程。

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

class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
		implements InstantiationAwareBeanPostProcessor, BeanFactoryAware{
    static {
            // 支持@WebServiceRef
            Class<? extends Annotation> clazz = (Class<? extends Annotation>)ClassUtils.forName("javax.xml.ws.WebServiceRef", CommonAnnotationBeanPostProcessor.class.getClassLoader());
            webServiceRefClass = clazz;

            // 支持@EJB
            Class<? extends Annotation> clazz = (Class<? extends Annotation>)ClassUtils.forName("javax.ejb.EJB", CommonAnnotationBeanPostProcessor.class.getClassLoader());
            ejbRefClass = clazz;

            // 支持@Resource
    		resourceAnnotationTypes.add(Resource.class);
    		if (webServiceRefClass != null) {
    			resourceAnnotationTypes.add(webServiceRefClass);
    		}
    		if (ejbRefClass != null) {
    			resourceAnnotationTypes.add(ejbRefClass);
    		}
    }
    public CommonAnnotationBeanPostProcessor() {
        setOrder(Ordered.LOWEST_PRECEDENCE - 3);
        // 初始化注解类型
        setInitAnnotationType(PostConstruct.class);
        // 销毁注解类型
        setDestroyAnnotationType(PreDestroy.class);
        ignoreResourceType("javax.xml.ws.WebServiceContext");
    }

	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
	    // 这个和Autowired不同的是,它除了处理@Resource还会处理生命周期注解@PostConstruct和销毁注解
		super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);{
		    // 查找生命周期的元数据
		    LifecycleMetadata metadata = findLifecycleMetadata(beanType);{
		        // 默认是不为空的
		        if (this.lifecycleMetadataCache == null) {
                    // 发生在反序列化之后,在销毁过程中
                    return buildLifecycleMetadata(clazz);
                }
                // 查询是否被处理过,存在缓存
                LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz);
                if (metadata == null) {
                    synchronized (this.lifecycleMetadataCache) {
                        // 加锁,双层校验
                        metadata = this.lifecycleMetadataCache.get(clazz);
                        if (metadata == null) {
                            // 构造生命周期元数据
                            metadata = buildLifecycleMetadata(clazz);{
                                // 判断类中是否存在指定的注解
                                // setInitAnnotationType(PostConstruct.class);
                                // setDestroyAnnotationType(PreDestroy.class);
                                if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
                                    return this.emptyLifecycleMetadata;
                                }
                                // 记录类中所有的初始化方法和销毁方法,包括父类
                                List<LifecycleElement> initMethods = new ArrayList<>();
                                List<LifecycleElement> destroyMethods = new ArrayList<>();
                                Class<?> targetClass = clazz;
                                do {
                                    // 当前类中包含的方法,不包括父类
                                    final List<LifecycleElement> currInitMethods = new ArrayList<>();
                                    final List<LifecycleElement> currDestroyMethods = new ArrayList<>();
                                    // 遍历所有的方法,找到方法中带有PostConstruct,或者PreDestroy的方法
                                    ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                                        if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
                                            // 将方法封装成LifecycleElement对象
                                            LifecycleElement element = new LifecycleElement(method);
                                            currInitMethods.add(element);
                                        }
                                        if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
                                            // 将方法封装成LifecycleElement对象
                                            currDestroyMethods.add(new LifecycleElement(method));
                                        }
                                    });
                                    // 保存当前类找到符合条件的方法
                                    initMethods.addAll(0, currInitMethods);
                                    destroyMethods.addAll(currDestroyMethods);
                                    // 继续找父类的方法
                                    targetClass = targetClass.getSuperclass();
                                }
                                while (targetClass != null && targetClass != Object.class);
                                // 如果存在初始化方法或者销毁方法,将他们封装成LifecycleMetadata对象
                                return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
                                        new LifecycleMetadata(clazz, initMethods, destroyMethods));
                            }
                            // 缓存元数据
                            this.lifecycleMetadataCache.put(clazz, metadata);
                        }
                        return metadata;
                    }
                }
                return metadata;
		    }
		    // 校验生命周期方法成员是不已经被管理了
            metadata.checkConfigMembers(beanDefinition);{
                Set<LifecycleElement> checkedInitMethods = new LinkedHashSet<>(this.initMethods.size());
                // 遍历所有生命周期方法的元素信息
                for (LifecycleElement element : this.initMethods) {
                    String methodIdentifier = element.getIdentifier();
                    // 判断methodIdentifier是不是由Spring管理和调用,默认返回false,表示不是Spring管理的
                    // 那么就需要交给Spring进行管理
                    if (!beanDefinition.isExternallyManagedInitMethod(methodIdentifier)) {
                        // 将方法交给Spring管理和调用
                        beanDefinition.registerExternallyManagedInitMethod(methodIdentifier);
                        // 保存被校验了的元素
                        checkedInitMethods.add(element);
                    }
                }
                // 和上面init方法一样
                Set<LifecycleElement> checkedDestroyMethods = new LinkedHashSet<>(this.destroyMethods.size());
                for (LifecycleElement element : this.destroyMethods) {
                    String methodIdentifier = element.getIdentifier();
                    if (!beanDefinition.isExternallyManagedDestroyMethod(methodIdentifier)) {
                        beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier);
                        checkedDestroyMethods.add(element);
                    }
                }
                // 这个保存的是所有没有被外部管理的配置成员的元素信息
                // 如果被外部成员管理,beanDefinition.isExternallyXXX(xx)就为true,表示已经被管理了
                // 就不需要再次管理,只需要管理一次
                this.checkedInitMethods = checkedInitMethods;
                this.checkedDestroyMethods = checkedDestroyMethods;
            }
		}
		// 找Resource注解的元信息
		InjectionMetadata metadata = findResourceMetadata(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 = buildResourceMetadata(clazz);{
                            // 确定当前类需要被注入,存在注入的注解
                            if (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) {
                                return InjectionMetadata.EMPTY;
                            }
                            // 保存所有需要注入的信息
                            List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
                            Class<?> targetClass = clazz;
                            do {
                                final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
                                // 找到当前注入类的所有字段,字段注入
                                ReflectionUtils.doWithLocalFields(targetClass, field -> {
                                    // 处理@WebServiceRefClass注解
                                    if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
                                        // @WebServiceRefClass不能标注在静态的字段中
                                        if (Modifier.isStatic(field.getModifiers())) {
                                            throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields");
                                        }
                                        // 封装成WebServiceRefElement元素对象
                                        currElements.add(new WebServiceRefElement(field, field, null));
                                    }
                                    // 处理@EJB注解
                                    else if (ejbRefClass != null && field.isAnnotationPresent(ejbRefClass)) {
                                        // @EJB不能标注在静态的字段中
                                        if (Modifier.isStatic(field.getModifiers())) {
                                            throw new IllegalStateException("@EJB annotation is not supported on static fields");
                                        }
                                        // 封装成EjbRefElement元素对象
                                        currElements.add(new EjbRefElement(field, field, null));
                                    }
                                    // 处理@Resource注解
                                    else if (field.isAnnotationPresent(Resource.class)) {
                                        // @Resource不能标注在静态的字段中
                                        if (Modifier.isStatic(field.getModifiers())) {
                                            throw new IllegalStateException("@Resource annotation is not supported on static fields");
                                        }
                                        // 封装成ResourceElement元素对象,当前字段没有被忽略
                                        if (!this.ignoredResourceTypes.contains(field.getType().getName())) {
                                            currElements.add(new ResourceElement(field, field, null){
                                                // 获取字段上的注解
                                                Resource resource = ae.getAnnotation(Resource.class);
                                                // 获取beanName
                                                String resourceName = resource.name();
                                                // 获取BeanType
                                                Class<?> resourceType = resource.type();
                                                // 如果没有指定beanName
                                                this.isDefaultName = !StringUtils.hasLength(resourceName);
                                                if (this.isDefaultName) {
                                                    // 使用字段名
                                                    resourceName = this.member.getName();
                                                    // 如果是方法注入,获取字段名
                                                    if (this.member instanceof Method && resourceName.startsWith("set") && resourceName.length() > 3) {
                                                        resourceName = Introspector.decapitalize(resourceName.substring(3));
                                                    }
                                                }
                                                // 如果给定了beanName,解析BeanName
                                                else if (embeddedValueResolver != null) {
                                                    resourceName = embeddedValueResolver.resolveStringValue(resourceName);
                                                }
                                                // 如果执行的BeanType,校验type和字段的type是否匹配
                                                if (Object.class != resourceType) {
                                                    checkResourceType(resourceType);
                                                }
                                                else {
                                                    如果没有指定BeanType,使用字段的类型
                                                    resourceType = getResourceType();
                                                }
                                                // beanName
                                                this.name = (resourceName != null ? resourceName : "");
                                                // beanType
                                                this.lookupType = resourceType;
                                                String lookupValue = resource.lookup();
                                                // 需要映射的名称
                                                this.mappedName = (StringUtils.hasLength(lookupValue) ? lookupValue : resource.mappedName());
                                                // 获取字段中是否存在Lazy注解
                                                Lazy lazy = ae.getAnnotation(Lazy.class);
                                                this.lazyLookup = (lazy != null && lazy.value());
                                            });
                                        }
                                    }
                                });
                                // 找到所有的方法,方法注入
                                // 和字段注入基本一样
                                ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                                    Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
                                    if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                                        return;
                                    }
                                    if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                                        if (webServiceRefClass != null && bridgedMethod.isAnnotationPresent(webServiceRefClass)) {
                                            // 方法不能是静态的
                                            if (Modifier.isStatic(method.getModifiers())) {
                                                throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods");
                                            }
                                            // 方法参数必须只有一个,也就是只能一次注入一个属性,而@Autowired可以注入多个
                                            if (method.getParameterCount() != 1) {
                                                throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
                                            }
                                            PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                                            currElements.add(new WebServiceRefElement(method, bridgedMethod, pd));
                                        }
                                        else if (ejbRefClass != null && bridgedMethod.isAnnotationPresent(ejbRefClass)) {
                                            // 方法不能是静态的
                                            if (Modifier.isStatic(method.getModifiers())) {
                                                throw new IllegalStateException("@EJB annotation is not supported on static methods");
                                            }
                                            // 方法参数必须只有一个,也就是只能一次注入一个属性,而@Autowired可以注入多个
                                            if (method.getParameterCount() != 1) {
                                                throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method);
                                            }
                                            PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                                            currElements.add(new EjbRefElement(method, bridgedMethod, pd));
                                        }
                                        else if (bridgedMethod.isAnnotationPresent(Resource.class)) {
                                            // 方法不能是静态的
                                            if (Modifier.isStatic(method.getModifiers())) {
                                                throw new IllegalStateException("@Resource annotation is not supported on static methods");
                                            }
                                            // 方法参数必须只有一个,也就是只能一次注入一个属性,而@Autowired可以注入多个
                                            Class<?>[] paramTypes = method.getParameterTypes();
                                            if (paramTypes.length != 1) {
                                                throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
                                            }
                                            if (!this.ignoredResourceTypes.contains(paramTypes[0].getName())) {
                                                PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                                                currElements.add(new ResourceElement(method, bridgedMethod, 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);
	}
    // 处理属性
	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
	    // 找到注入的原信息,在postProcessMergedBeanDefinition的时候就已经缓存了
        InjectionMetadata metadata = findResourceMetadata(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);{
                        // 如果是字段
                        if (this.isField) {
                            Field field = (Field) this.member;
                            ReflectionUtils.makeAccessible(field);
                            // 反射设置,这个不同的注解实现不同,我们只讲@Resource,ResourceElement,在上面方法已经处理过了,保存起来了
                            field.set(target, getResourceToInject(target, requestingBeanName){
                                // 字段是否存在@Lazy,如果存在
                                return (this.lazyLookup ?
                                                          // 生成代理
                                                          buildLazyResourceProxy(this, requestingBeanName){
                                                            TargetSource ts = new TargetSource() {
                                                                @Override
                                                                public Class<?> getTargetClass() {
                                                                    // 返回beanType
                                                                    return element.lookupType;
                                                                }
                                                                @Override
                                                                public Object getTarget() {
                                                                    // 返回
                                                                    return getResource(element, requestingBeanName);{
                                                                        // 如果存在mappedName,表示@Resource写了lookup,从jndi中获取Bean进行注入
                                                                        if (StringUtils.hasLength(element.mappedName)) {
                                                                            return this.jndiFactory.getBean(element.mappedName, element.lookupType);
                                                                        }
                                                                        // 默认为false,从jndi中获取Bean进行注入
                                                                        if (this.alwaysUseJndiLookup) {
                                                                            return this.jndiFactory.getBean(element.name, element.lookupType);
                                                                        }
                                                                        // 由于CommonAnnotationBeanPostProcessor实现了BeanFactoryAware
                                                                        // 在setBeanFactory中,将this.resourceFactory = beanFactory(DefaultListableBeanFactory);
                                                                        // 所以这里肯定不为空
                                                                        if (this.resourceFactory == null) {
                                                                            throw new NoSuchBeanDefinitionException(element.lookupType,
                                                                                    "No resource factory configured - specify the 'resourceFactory' property");
                                                                        }
                                                                        // 注入Bean
                                                                        return autowireResource(this.resourceFactory, element, requestingBeanName);{
                                                                            Object resource;
                                                                            Set<String> autowiredBeanNames;
                                                                            String name = element.name;
                                                                            // 符合条件,因为setBeanFactory设置的实DefaultListableBeanFactory
                                                                            if (factory instanceof AutowireCapableBeanFactory) {
                                                                                AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory;
                                                                                DependencyDescriptor descriptor = element.getDependencyDescriptor();
                                                                                // 如果@Resource没有给定beanName,同时使用默认的名称,并且容器中不存在这个名称的情况下
                                                                                if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) {
                                                                                    autowiredBeanNames = new LinkedHashSet<>();
                                                                                    // 解析Bean依赖,并将解析的BeanName保存到autowiredBeanNames中
                                                                                    resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);
                                                                                    // 如果没有找到对应的Bean,无法注入,直接抛异常
                                                                                    if (resource == null) {
                                                                                        throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
                                                                                    }
                                                                                }
                                                                                // 给定了名称,或者容器中包含了beanName
                                                                                else {
                                                                                    // 直接从容器中获取Bean
                                                                                    resource = beanFactory.resolveBeanByName(name, descriptor);
                                                                                    // 并且保存BeanName
                                                                                    autowiredBeanNames = Collections.singleton(name);
                                                                                }
                                                                            }
                                                                            // 如果factory不是AutowireCapableBeanFactory类型,其他的BeanFactory类型,都直接获取Bean
                                                                            else {
                                                                                // 直接调用factory的getBean方法
                                                                                resource = factory.getBean(name, element.lookupType);
                                                                                // 并且保存BeanName
                                                                                autowiredBeanNames = Collections.singleton(name);
                                                                            }
                                                                            // 如果factory又是ConfigurableBeanFactory
                                                                            // 保存bean之间的依赖关系
                                                                            if (factory instanceof ConfigurableBeanFactory) {
                                                                                ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory) factory;
                                                                                // 遍历上面处理过的beanName
                                                                                for (String autowiredBeanName : autowiredBeanNames) {
                                                                                    // beanName在工厂中存在
                                                                                    if (requestingBeanName != null && beanFactory.containsBean(autowiredBeanName)) {
                                                                                        // 保存Bean的依赖关系
                                                                                        beanFactory.registerDependentBean(autowiredBeanName, requestingBeanName);
                                                                                    }
                                                                                }
                                                                            }

                                                                            return resource;
                                                                        }
                                                                    }
                                                                }
                                                            };
                                                            // 生成代理对象
                                                            ProxyFactory pf = new ProxyFactory();
                                                            pf.setTargetSource(ts);
                                                            if (element.lookupType.isInterface()) {
                                                                pf.addInterface(element.lookupType);
                                                            }
                                                            ClassLoader classLoader = (this.beanFactory instanceof ConfigurableBeanFactory ? ((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() : null);
                                                            return pf.getProxy(classLoader);
                                                          } :
                                                            // 上面已经有对方法的详解,public Object getTarget()
                                                            getResource(this, requestingBeanName));
                            });
                        }
                        // 如果是方法,进行方法注入,和字段注入一样
                        else {
                            if (checkPropertySkipping(pvs)) {
                                return;
                            }
                            Method method = (Method) this.member;
                            ReflectionUtils.makeAccessible(method);
                            method.invoke(target, getResourceToInject(target, requestingBeanName));
                        }
                    }
                }
            }
        }
        return pvs;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值