基于Annotation的依赖注入

1.注解配置

类内部的注解,如:@Autowire@Value@Required@Resource以及EJBWebSerivce相关的注解,是容器对Bean对象实例化和依赖注入时,通过容器中注册的Bean后置处理器处理这些注解的.

Spring中处理注解的Bean后置处理器:当使用Spring的注解功能时,在Spring配置文件中添加如下配置开启Spring的注解处理器:

<context:annotation-config>  
<context:component-scan >

上面的配置将隐式地向Spring容器注册4个专门用于处理注解的Bean后置处理器

  • AutowiredAnnotationBeanPostProcessor
  • CommonAnnotationBeanPostProcessor
  • RequiredAnnotationBeanPostProcessor
  • PersistenceAnnotationBeanPostProcessor

2.AutowiredAnnotationBeanPostProcessor

AutowiredAnnotationBeanPostProcessor是Spring容器专门处理配置了自动依赖注入装配相关注解(@Autowire@Value以及其他JSR-330注解)的Bean后置处理器,其主要功能源码如下:

2.1 构造方法

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
        implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {

    /**
     * Create a new AutowiredAnnotationBeanPostProcessor
     * for Spring's standard {@link Autowired} annotation.
     * <p>Also supports JSR-330's {@link javax.inject.Inject} annotation, if available.
     */
    @SuppressWarnings("unchecked")
    public AutowiredAnnotationBeanPostProcessor() {
        // 后置处理器将处理@Autowire注解
        this.autowiredAnnotationTypes.add(Autowired.class);
        // 后置处理器将处理@Value注解
        this.autowiredAnnotationTypes.add(Value.class);
        try {
            // 后置处理器将处理javax.inject.Inject JSR-330注解
            this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
                    ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
            logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
        }
        catch (ClassNotFoundException ex) {
            // JSR-330 API not available - simply skip.
        }
    }
}

2.2 为指定类选择其合适的构造方法

容器对指定类进行自动依赖注入装配(autowiring)时,容器需要对Bean调用合适的构造方法创建实例对象,AutowiredAnnotationBeanPostProcessor为指定类选择相应的构造方法,源码如下:

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
        implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {

    /**
     * 为自动依赖注入装配Bean选择合适的构造方法
     * 解析Bean类里构造函数上的@Autowired注解,如果有合适的标识了@Autowired的构造函数,则在实例化此Bean时会使用此构造函数,
     * @Import@ComponentScan得到的Bean会如此解析,@Bean标识方法生成的Bean不会如此
     */
    @Override
    @Nullable
    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, method -> {
                    Lookup lookup = method.getAnnotation(Lookup.class);
                    if (lookup != null) {
                        Assert.state(this.beanFactory != null, "No BeanFactory available");
                        LookupOverride override = new LookupOverride(method, lookup.value());
                        try {
                            RootBeanDefinition mbd = (RootBeanDefinition) this.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);
            }
            this.lookupMethodsChecked.add(beanName);
        }

        // Quick check on the concurrent map first, with minimal locking.
        // 从容器的缓存中查找是否有指定Bean的构造方法
        Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
        // 容器缓存中没有给定类的构造方法
        if (candidateConstructors == null) {
            // Fully synchronized resolution now...
            // 线程同步以确保容器中数据一致性
            synchronized (this.candidateConstructorsCache) {
                candidateConstructors = this.candidateConstructorsCache.get(beanClass);
                if (candidateConstructors == null) {
                    // 通过JDK反射机制,获取指定类的中所有声明的构造方法
                    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<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
                    // autowire注解中required属性指定的构造方法
                    Constructor<?> requiredConstructor = null;
                    // 默认的构造方法
                    Constructor<?> defaultConstructor = null;
                    Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
                    int nonSyntheticConstructors = 0;
                    // 遍历所有的构造方法,检查是否添加了autowire注解,以及是否指定了required属性
                    for (Constructor<?> candidate : rawCandidates) {
                        if (!candidate.isSynthetic()) {
                            nonSyntheticConstructors++;
                        }
                        else if (primaryConstructor != null) {
                            continue;
                        }
                        // 获取指定类中所有关于autowired的注解(Annotation)
                        AnnotationAttributes ann = findAutowiredAnnotation(candidate);
                        if (ann == null) {
                            Class<?> userClass = ClassUtils.getUserClass(beanClass);
                            if (userClass != beanClass) {
                                try {
                                    Constructor<?> superCtor =
                                            userClass.getDeclaredConstructor(candidate.getParameterTypes());
                                    ann = findAutowiredAnnotation(superCtor);
                                }
                                catch (NoSuchMethodException ex) {
                                    // Simply proceed, no equivalent superclass constructor found...
                                }
                            }
                        }
                        // 如果指定类中有关于autowired的注解
                        if (ann != null) {
                            // 如果autowired注解中指定了required属性
                            if (requiredConstructor != null) {
                                throw new BeanCreationException(beanName,
                                        "Invalid autowire-marked constructor: " + candidate +
                                        ". Found constructor with 'required' Autowired annotation already: " +
                                        requiredConstructor);
                            }
                            // 获取autowire注解中required属性值
                            boolean required = determineRequiredStatus(ann);
                            // 如果获取到autowire注解中required的属性值
                            if (required) {
                                // 如果候选构造方法集合不为空
                                if (!candidates.isEmpty()) {
                                    throw new BeanCreationException(beanName,
                                            "Invalid autowire-marked constructors: " + candidates +
                                            ". Found constructor with 'required' Autowired annotation: " +
                                            candidate);
                                }
                                // 当前的构造方法就是required属性所配置的构造方法
                                requiredConstructor = candidate;
                            }
                            // 将当前的构造方法添加到候选构造方法集合中
                            candidates.add(candidate);
                        }
                        // 如果类中没有autowired的相关注解,并且构造方法参数列表为空
                        else if (candidate.getParameterCount() == 0) {
                            // 当前的构造方法是默认构造方法
                            defaultConstructor = candidate;
                        }
                    }
                    // 如果候选构造方法集合不为空
                    if (!candidates.isEmpty()) {
                        // Add default constructor to list of optional constructors, as fallback.
                        // 如果所有的构造方法都没有配置required属性,且有默认构造方法
                        if (requiredConstructor == null) {
                            if (defaultConstructor != null) {
                                //将默认构造方法添加到候选构造方法列表
                                candidates.add(defaultConstructor);
                            }
                            else if (candidates.size() == 1 && logger.isInfoEnabled()) {
                                logger.info("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<?>[0]);
                    }
                    else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
                        candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
                    }
                    else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
                            defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
                        candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
                    }
                    else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
                        candidateConstructors = new Constructor<?>[] {primaryConstructor};
                    }
                    // 如果候选构造方法集合为空,则创建一个空的数组
                    else {
                        candidateConstructors = new Constructor<?>[0];
                    }
                    // 将类的候选构造方法集合存放到容器的缓存中
                    this.candidateConstructorsCache.put(beanClass, candidateConstructors);
                }
            }
        }
        // 返回指定类的候选构造方法数组,如果没有返回null
        return (candidateConstructors.length > 0 ? candidateConstructors : null);
    }
}

2.3 方法和属性的依赖注入

当Spring容器对配置了autowire相关注解的Bean进行依赖注入时,后置处理器对属性和对象进行自动注入处理,源码如下:

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
        implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {

    /**
     * 处理类中属性
     */
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        // 获取指定类中autowired相关注解的元信息
        InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
        try {
            // 对Bean的属性进行自动注入
            metadata.inject(bean, beanName, pvs);
        }
        catch (BeanCreationException ex) {
            throw ex;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
        }
        return pvs;
    }

    /**
     * 处理对象的注入
     * 'Native' processing method for direct calls with an arbitrary target instance,
     * resolving all of its fields and methods which are annotated with {@code @Autowired}.
     * @param bean the target instance to process
     * @throws BeanCreationException if autowiring failed
     */
    public void processInjection(Object bean) throws BeanCreationException {
        // 获取给定Bean的Class对象
        Class<?> clazz = bean.getClass();
        // 获取给定类中autowire相关注解元信息
        InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz, null);
        try {
            // 对Bean对象进行自动注入
            metadata.inject(bean, null, null);
        }
        catch (BeanCreationException ex) {
            throw ex;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    "Injection of autowired dependencies failed for class [" + clazz + "]", ex);
        }
    }

    /**
     * 获取给定类的autowired相关注解元信息
     */
    private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
        // Fall back to class name as cache key, for backwards compatibility with custom callers.
        String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
        // Quick check on the concurrent map first, with minimal locking.
        // 从容器中查找是否有给定类的autowired相关注解元信息
        InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
        if (InjectionMetadata.needsRefresh(metadata, clazz)) {
            synchronized (this.injectionMetadataCache) {
                metadata = this.injectionMetadataCache.get(cacheKey);
                if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                    if (metadata != null) {
                        metadata.clear(pvs);
                    }
                    // 解析给定类autowired相关注解元信息
                    metadata = buildAutowiringMetadata(clazz);
                    // 将得到的给定类autowired相关注解元信息存储在容器缓存中
                    this.injectionMetadataCache.put(cacheKey, metadata);
                }
            }
        }
        return metadata;
    }

    /**
     * 解析给定类autowired相关注解元信息
     */
    private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
        // 创建一个存放注解元信息的集合
        List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
        Class<?> targetClass = clazz;

        //递归遍历当前类及其所有基类,解析全部注解元信息
        do {
            // 创建一个存储当前正在处理类注解元信息的集合
            final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

            // 利用JDK反射机制获取给定类中所有的声明字段,获取字段上的注解信息
            ReflectionUtils.doWithLocalFields(targetClass, field -> {
                // 获取给定字段上的注解
                AnnotationAttributes ann = findAutowiredAnnotation(field);
                if (ann != null) {
                    // 如果给定字段是静态的(Static),则直接遍历下一个字段
                    if (Modifier.isStatic(field.getModifiers())) {
                        if (logger.isInfoEnabled()) {
                            logger.info("Autowired annotation is not supported on static fields: " + field);
                        }
                        return;
                    }
                    // 判断注解的required属性值是否有效
                    boolean required = determineRequiredStatus(ann);
                    // 将当前字段元信息封装,添加在返回的集合中
                    currElements.add(new AutowiredFieldElement(field, required));
                }
            });

            // 利用JDK反射机制获取给定类中所有的声明方法,获取方法上的注解信息
            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.isInfoEnabled()) {
                            logger.info("Autowired annotation is not supported on static methods: " + method);
                        }
                        return;
                    }
                    // 如果方法的参数列表为空
                    if (method.getParameterCount() == 0) {
                        if (logger.isInfoEnabled()) {
                            logger.info("Autowired annotation should only be used on methods with parameters: " +
                                    method);
                        }
                    }
                    // 如果方法的参数列表为空
                    boolean required = determineRequiredStatus(ann);
                    // 获取当前方法的属性描述符,即方法是可读的(readable)getter方法,还是可写的(writeable)setter方法
                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                    // 将方法元信息封装添加到返回的元信息集合中
                    currElements.add(new AutowiredMethodElement(method, required, pd));
                }
            });

            // 将当前类的注解元信息存放到注解元信息集合中
            elements.addAll(0, currElements);
            // 获取给定类的父类
            targetClass = targetClass.getSuperclass();
        }
        // 如果给定类有基类,并且基类不是Object,则递归获取其基类的元信息
        while (targetClass != null && targetClass != Object.class);

        return new InjectionMetadata(clazz, elements);
    }
}

2.4 对字段和方法的注入

2.4.1 对字段的注入

对字段的注入是通过AutowiredFieldElement类的inject方法实现的,源码如下:

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
        implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {

    /**
     * 对字段进行注入
     * Class representing injection information about an annotated field.
     */
    private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {

        private final boolean required;

        private volatile boolean cached = false;

        @Nullable
        private volatile Object cachedFieldValue;

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

        @Override
        protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
            // 获取注入元素对象
            Field field = (Field) this.member;
            Object value;
            // 如果当前对象在容器中被缓存
            if (this.cached) {
                // 根据Bean名称解析缓存中的字段值
                value = resolvedCachedArgument(beanName, this.cachedFieldValue);
            }
            // 如果当前对象没有被容器缓存
            else {
                // 创建一个字段依赖描述符
                DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
                desc.setContainingClass(bean.getClass());
                Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
                Assert.state(beanFactory != null, "No BeanFactory available");
                // 获取容器中的类型转换器
                TypeConverter typeConverter = beanFactory.getTypeConverter();
                try {
                    // 根据容器中Bean定义,解析指定的依赖关系,获取依赖对象
                    value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
                }
                catch (BeansException ex) {
                    throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
                }
                // 线程同步,确保容器中数据一致性
                synchronized (this) {
                    // 如果当前对象没有被容器缓存
                    if (!this.cached) {
                        // 获取到了当前对象的依赖对象,并且required属性为true
                        if (value != null || this.required) {
                            this.cachedFieldValue = desc;
                            // 为指定Bean注册依赖Bean
                            registerDependentBeans(beanName, autowiredBeanNames);
                            if (autowiredBeanNames.size() == 1) {
                                String autowiredBeanName = autowiredBeanNames.iterator().next();
                                //如果容器中有指定名称的Bean对象
                                if (beanFactory.containsBean(autowiredBeanName) &&
                                        // 依赖对象类型和字段类型匹配,默认按类型注入
                                        beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
                                    // 创建一个依赖对象的引用,同时缓存
                                    this.cachedFieldValue = new ShortcutDependencyDescriptor(
                                            desc, autowiredBeanName, field.getType());
                                }
                            }
                        }
                        // 如果获取的依赖关系为null,且获取required属性为false
                        else {
                            // 将字段值的缓存设置为null
                            this.cachedFieldValue = null;
                        }
                        // 容器已经对当前字段的值缓存
                        this.cached = true;
                    }
                }
            }
            // 如果字段依赖值不为null
            if (value != null) {
                // 显式使用JDK的反射机制,设置自动的访问控制权限为允许访问
                ReflectionUtils.makeAccessible(field);
                // 为Bean对象的字段设置值
                field.set(bean, value);
            }
        }
    }
}

2.4.2 对方法的注入

对方法的注入是通过AutowiredMethodElement类的inject方法实现的,源码如下:

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
        implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {

    /**
     * 对方法进行注入
     * Class representing injection information about an annotated method.
     */
    private class AutowiredMethodElement extends InjectionMetadata.InjectedElement {

        private final boolean required;

        private volatile boolean cached = false;

        @Nullable
        private volatile Object[] cachedMethodArguments;

        public AutowiredMethodElement(Method method, boolean required, @Nullable PropertyDescriptor pd) {
            super(method, pd);
            this.required = required;
        }

        @Override
        protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
            // 如果属性被显式设置为skip,则不进行注入
            if (checkPropertySkipping(pvs)) {
                return;
            }

            // 获取注入元素对象
            Method method = (Method) this.member;
            Object[] arguments;
            // 如果容器对当前方法缓存
            if (this.cached) {
                // Shortcut for avoiding synchronization...
                // 获取缓存中指定Bean名称的方法参数
                arguments = resolveCachedArguments(beanName);
            }
            // 如果没有缓存
            else {
                // 获取方法的参数列表
                Class<?>[] paramTypes = method.getParameterTypes();
                // 创建一个存放方法参数的数组
                arguments = new Object[paramTypes.length];
                DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length];
                Set<String> autowiredBeans = new LinkedHashSet<>(paramTypes.length);
                Assert.state(beanFactory != null, "No BeanFactory available");
                // 获取容器的类型转换器
                TypeConverter typeConverter = beanFactory.getTypeConverter();
                for (int i = 0; i < arguments.length; i++) {
                    // 创建方法参数对象
                    MethodParameter methodParam = new MethodParameter(method, i);
                    // 解析方法的输入参数和返回值类型 GenericTypeResolver.resolveParameterType(methodParam, bean.getClass());, 为方法参数创建依赖描述符
                    DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
                    currDesc.setContainingClass(bean.getClass());
                    descriptors[i] = currDesc;
                    try {
                        // 根据容器中Bean定义解析依赖关系,获取方法参数依赖对象
                        Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
                        // 如果容器解析的方法参数为null,且方法required属性为false
                        if (arg == null && !this.required) {
                            // 设置方法的参数列表为null  
                            arguments = null;
                            break;
                        }
                        arguments[i] = arg;
                    }
                    catch (BeansException ex) {
                        throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
                    }
                }
                // 线程同步,以确保容器中数据一致性
                synchronized (this) {
                    // 如果当前方法没有被容器缓存
                    if (!this.cached) {
                        // 如果方法的参数列表不为空
                        if (arguments != null) {
                            // 为容器中缓存方法参数的对象赋值
                            Object[] cachedMethodArguments = new Object[paramTypes.length];
                            System.arraycopy(descriptors, 0, cachedMethodArguments, 0, arguments.length);
                            // 为指定Bean注册依赖Bean
                            registerDependentBeans(beanName, autowiredBeans);
                            // 如果依赖对象集合大小等于方法参数个数
                            if (autowiredBeans.size() == paramTypes.length) {
                                Iterator<String> it = autowiredBeans.iterator();
                                // 为方法参数设置依赖对象
                                for (int i = 0; i < paramTypes.length; i++) {
                                    String autowiredBeanName = it.next();
                                    // 如果容器中存在指定名称的Bean对象
                                    if (beanFactory.containsBean(autowiredBeanName) &&
                                            // 如果参数类型和依赖对象类型匹配
                                            beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
                                        //创建一个依赖对象的引用,复制给方法相应的参数 this.cachedMethodArguments[i] = new RuntimeBeanReference(autowiredBeanName);
                                        cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
                                                descriptors[i], autowiredBeanName, paramTypes[i]);
                                    }
                                }
                            }
                            this.cachedMethodArguments = cachedMethodArguments;
                        }
                        // 如果方法参数列表为null,则设置容器对该方法参数的缓存为null
                        else {
                            this.cachedMethodArguments = null;
                        }
                        // 设置容器已经对该方法缓存
                        this.cached = true;
                    }
                }
            }
            // 如果方法参数依赖对象不为null
            if (arguments != null) {
                try {
                    // 使用JDK的反射机制,显式设置方法的访问控制权限为允许访问
                    ReflectionUtils.makeAccessible(method);
                    // 调用Bean的指定方法
                    method.invoke(bean, arguments);
                }
                catch (InvocationTargetException ex){
                    throw ex.getTargetException();
                }
            }
        }

        @Nullable
        private Object[] resolveCachedArguments(@Nullable String beanName) {
            Object[] cachedMethodArguments = this.cachedMethodArguments;
            if (cachedMethodArguments == null) {
                return null;
            }
            Object[] arguments = new Object[cachedMethodArguments.length];
            for (int i = 0; i < arguments.length; i++) {
                arguments[i] = resolvedCachedArgument(beanName, cachedMethodArguments[i]);
            }
            return arguments;
        }
    }
}

3.CommonAnnotationBeanPostProcessor

CommonAnnotationBeanPostProcessor是Spring中用于处理JavaEE5中常用注解(主要是EJB相关的注解)和Java6中关于JAX-WS相关的注解,可以处理PostConstruct@PreDestroy等Bean生命周期相关事件的注解,该后置处理最核心的是处理@Resource注解,同时还可以处理JAX-WS相关的注解,按照其主要功能分析其主要实现源码.

3.1 静态初始化块和构造函数

public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
        implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {

    /**
     * WebService关于JAX-WS的相关注解
     */
    @Nullable
    private static Class<? extends Annotation> webServiceRefClass;

    /**
     * EJB相关的注解
     */
    @Nullable
    private static Class<? extends Annotation> ejbRefClass;

    /**
     * 静态初始化块
     */
    static {
        try {
            // 使用类加载器加载WebService相关的类
            @SuppressWarnings("unchecked")
            Class<? extends Annotation> clazz = (Class<? extends Annotation>)
                    ClassUtils.forName("javax.xml.ws.WebServiceRef", CommonAnnotationBeanPostProcessor.class.getClassLoader());
            webServiceRefClass = clazz;
        }
        catch (ClassNotFoundException ex) {
            webServiceRefClass = null;
        }
        try {
            // 使用类加载器加载EJB相关的类
            @SuppressWarnings("unchecked")
            Class<? extends Annotation> clazz = (Class<? extends Annotation>)
                    ClassUtils.forName("javax.ejb.EJB", CommonAnnotationBeanPostProcessor.class.getClassLoader());
            ejbRefClass = clazz;
        }
        catch (ClassNotFoundException ex) {
            ejbRefClass = null;
        }
    }

    /**
     * Create a new CommonAnnotationBeanPostProcessor,
     * with the init and destroy annotation types set to
     * {@link javax.annotation.PostConstruct} and {@link javax.annotation.PreDestroy},
     * respectively.
     */
    public CommonAnnotationBeanPostProcessor() {
        setOrder(Ordered.LOWEST_PRECEDENCE - 3);
        // 设置初始的注解类型为@PostConstruct
        setInitAnnotationType(PostConstruct.class);
        // 设置消耗的注解为@PreDestroy
        setDestroyAnnotationType(PreDestroy.class);
        // 当使用@Resource注解时,忽略JAX-WS的资源类型
        ignoreResourceType("javax.xml.ws.WebServiceContext");
    }
}

CommonAnnotationBeanPostProcessor的静态初始化块和构造方法可以看出该后置处理器主要处理EJB和WebService相关的注解,以及Bean生命周期事件的相关注解.

3.2 CommonAnnotationBeanPostProcessor对属性值的查找

CommonAnnotationBeanPostProcessor对普通属性的处理与AutowiredAnnotationBeanPostProcessor的处理基本相同,不同在于查找属性值的方法不同,通过autowire相关注解的required配置获取依赖的属性值,则通过对@Resource注解的解析获取属性的值,CommonAnnotationBeanPostProcessor获取属性值的主要源码:

public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
        implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {

    /**
     * 处理属性值
     */
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        // 获取@Resource注解中配置的属性值元数据
        InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
        try {
            // 注入属性值,与AutowiredAnnotationBeanPostProcessor中处理相同
            metadata.inject(bean, beanName, pvs);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
        }
        return pvs;
    }

    /**
     * 获取@Resource注解中配置的属性值元数据
     */
    private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz, @Nullable PropertyValues pvs) {
        // Fall back to class name as cache key, for backwards compatibility with custom callers.
        String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
        // Quick check on the concurrent map first, with minimal locking.
        // 从容器缓存中查找
        InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
        // 缓存中没有给定类的注解元信息数据
        if (InjectionMetadata.needsRefresh(metadata, clazz)) {
            // 线程同步,以确保容器中数据一致
            synchronized (this.injectionMetadataCache) {
                metadata = this.injectionMetadataCache.get(cacheKey);
                if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                    if (metadata != null) {
                        metadata.clear(pvs);
                    }
                    metadata = buildResourceMetadata(clazz);
                    // 缓存给定类的注解元信息
                    this.injectionMetadataCache.put(cacheKey, metadata);
                }
            }
        }
        return metadata;
    }

    private InjectionMetadata buildResourceMetadata(final Class<?> clazz) {
        // 创建一个用于存放注解元数据的集合
        List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
        Class<?> targetClass = clazz;

        // 递归地的解析给定类及其所有基类的注解元信息
        do {
            // 创建一个存放当前类注解元数据的集合
            final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

            // 遍历给定类中所有的字段,查找符合的注解
            ReflectionUtils.doWithLocalFields(targetClass, field -> {
                // 如果字段上配置了WebService相关的注解
                if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
                    // 如果字段是静态的,则注解对静态字段无效
                    if (Modifier.isStatic(field.getModifiers())) {
                        throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields");
                    }
                    // 如果字段不是静态,则将当前字段封装为WebService引用元素
                    currElements.add(new WebServiceRefElement(field, field, null));
                }
                // 如果当前字段上配置了EJB相关的注解
                else if (ejbRefClass != null && field.isAnnotationPresent(ejbRefClass)) {
                    if (Modifier.isStatic(field.getModifiers())) {
                        throw new IllegalStateException("@EJB annotation is not supported on static fields");
                    }
                    // 将当前字段封装为EJB引用元素
                    currElements.add(new EjbRefElement(field, field, null));
                }
                // 如果当前字段上配置了@Resource注解
                else if (field.isAnnotationPresent(Resource.class)) {
                    if (Modifier.isStatic(field.getModifiers())) {
                        throw new IllegalStateException("@Resource annotation is not supported on static fields");
                    }
                    //如果当前自动的类型不在被忽略的Resource类型中,则将当前字段封装为资源元素
                    if (!this.ignoredResourceTypes.contains(field.getType().getName())) {
                        currElements.add(new ResourceElement(field, field, null));
                    }
                }
            });

            // 遍历给定类中的所有方法,查找相关的注解
            ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
                if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                    return;
                }
                if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                    // 如果方法上配置了WebService相关的注解
                    if (webServiceRefClass != null && bridgedMethod.isAnnotationPresent(webServiceRefClass)) {
                        // 如方法是静态的,则注解不支持静态方法
                        if (Modifier.isStatic(method.getModifiers())) {
                            throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods");
                        }
                        // 如果方法参数个数不等于1
                        if (method.getParameterCount() != 1) {
                            throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
                        }
                        // 获取方法的属性描述
                        PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                        // 将当前方法对象和方法属性描述封装为WebService引用元素
                        currElements.add(new WebServiceRefElement(method, bridgedMethod, pd));
                    }
                    // 如果方法上配置了EJB相关的注解
                    else if (ejbRefClass != null && bridgedMethod.isAnnotationPresent(ejbRefClass)) {
                        if (Modifier.isStatic(method.getModifiers())) {
                            throw new IllegalStateException("@EJB annotation is not supported on static methods");
                        }
                        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));
                    }
                    // 如果方法上配置了@Resource注解
                    else if (bridgedMethod.isAnnotationPresent(Resource.class)) {
                        if (Modifier.isStatic(method.getModifiers())) {
                            throw new IllegalStateException("@Resource annotation is not supported on static methods");
                        }
                        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();
        }
        // 如果基类不为null,且基类不是Object
        while (targetClass != null && targetClass != Object.class);

        return new InjectionMetadata(clazz, elements);
    }
}

从上面的源码中,我们可以看到,对于方法上面的注解,EJBWebService相关注解以及@Resource只能在单个参数的方法上配置,否则会有异常抛出.

3.3 根据给定名称或者类型获取资源对象

WebServiceEJB相关注解以及@Resource主要是为所添加的字段或者方法注入所需要的资源,CommonAnnotationBeanPostProcessor类中获取资源的源码如下:

public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
        implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {

    /**
     * 根据给定名称或者类型获取资源对象
     */
    protected Object getResource(LookupElement element, @Nullable String requestingBeanName)
            throws NoSuchBeanDefinitionException {

        // 如果注解对象元素的mappedName属性不为空
        if (StringUtils.hasLength(element.mappedName)) {
            // 根据JNDI名称和类型去Spring的JNDI容器中获取Bean
            return this.jndiFactory.getBean(element.mappedName, element.lookupType);
        }
        // 如果该后置处理器的alwaysUseJndiLookup属性值为true
        if (this.alwaysUseJndiLookup) {
            //从Spring的JNDI容器中查找指定JDNI名称和类型的Bean
            return this.jndiFactory.getBean(element.name, element.lookupType);
        }
        if (this.resourceFactory == null) {
            throw new NoSuchBeanDefinitionException(element.lookupType,
                    "No resource factory configured - specify the 'resourceFactory' property");
        }
        // 使用autowiring自动依赖注入装配,通过给定的名称和类型从资源容器获取Bean对象
        return autowireResource(this.resourceFactory, element, requestingBeanName);
    }

    /**
     * 自动依赖注入装配资源对象
     */
    protected Object autowireResource(BeanFactory factory, LookupElement element, @Nullable String requestingBeanName)
            throws NoSuchBeanDefinitionException {

        Object resource;
        Set<String> autowiredBeanNames;
        String name = element.name;

        if (this.fallbackToDefaultTypeMatch && element.isDefaultName &&
                factory instanceof AutowireCapableBeanFactory && !factory.containsBean(name)) {
            autowiredBeanNames = new LinkedHashSet<>();

            // 根据容器中Bean定义解析给定的依赖关系,将依赖以资源对象返回
            resource = ((AutowireCapableBeanFactory) factory).resolveDependency(
                    element.getDependencyDescriptor(), requestingBeanName, autowiredBeanNames, null);
            if (resource == null) {
                throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
            }
        }
        // 根据给定JDNI名称和类型从Spring的JDNI容器查找资源
        else {
            resource = factory.getBean(name, element.lookupType);
            autowiredBeanNames = Collections.singleton(name);
        }

        // 为指定的Bean注册依赖的Bean
        if (factory instanceof ConfigurableBeanFactory) {
            ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory) factory;
            for (String autowiredBeanName : autowiredBeanNames) {
                if (requestingBeanName != null && beanFactory.containsBean(autowiredBeanName)) {
                    beanFactory.registerDependentBean(autowiredBeanName, requestingBeanName);
                }
            }
        }

        return resource;
    }
}

4.@Resource、WebService和EJB相关注解的解析和属性注入

Spring中,@Resource注解是由ResourceElement类解析的,WebService相关注解是由WebServiceRefElement类解析的,EJB相关注解是由EjbRefElement类解析的,下面就具体分析其解析的实现

4.1 ResourceElement解析@Resource注解和属性注入

ResourceElement是Spring中用于解析@Resource注解和属性注入的类,源码如下:

public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
        implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {

    private class ResourceElement extends LookupElement {
        private final boolean lazyLookup;

        /**
         * 解析@Resource注解
         * @param member
         * @param ae
         * @param pd
         */
        public ResourceElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) {
            super(member, pd);
            // 获取元素对象的@Resource注解
            Resource resource = ae.getAnnotation(Resource.class);
            // 获取@Resource注解的name属性值作为资源名称
            String resourceName = resource.name();
            // 获取@Resource注解的type属性值作为资源类型
            Class<?> resourceType = resource.type();
            // 根据注解配置的资源名称是否为空,判断元素是否有默认名称
            this.isDefaultName = !StringUtils.hasLength(resourceName);
            // 如果元素有默认名称
            if (this.isDefaultName) {
                // 获取元素对象名称作为资源名称
                resourceName = this.member.getName();
                // 如果当前添加注解的对象是方法,且方法名称以set开头,且属性名称不为空(方法名长度大于3,即除了set之外还有其他字符)
                if (this.member instanceof Method && resourceName.startsWith("set") && resourceName.length() > 3) {
                    // 利用JDK的内省机制格式化对象名称,转换为Java标准的驼峰命名法
                    resourceName = Introspector.decapitalize(resourceName.substring(3));
                }
            }
            // 如果当前的容器是ConfigurableBeanFactory类型容器
            else if (embeddedValueResolver != null) {
                // 解析给定的对象名的内嵌值做为资源名称
                resourceName = embeddedValueResolver.resolveStringValue(resourceName);
            }
            // 如果注解配置的资源类型不为空,且不说Object类型
            if (Object.class != resourceType) {
                // 检查资源类型是字段还是方法
                checkResourceType(resourceType);
            }
            else {
                // No resource type specified... check field/method.
                // 如果注解中没有配置资源类型,则利用JDK反射机制判断是字段还是方法
                resourceType = getResourceType();
            }
            // 设置当前注解元素的资源名称
            this.name = (resourceName != null ? resourceName : "");
            // 设置当前注解元素的JNDI类型
            this.lookupType = resourceType;
            String lookupValue = resource.lookup();
            // 获取@Resource注解的mappedName属性值,设置当前注解元素的JNDI名称
            this.mappedName = (StringUtils.hasLength(lookupValue) ? lookupValue : resource.mappedName());
            Lazy lazy = ae.getAnnotation(Lazy.class);
            this.lazyLookup = (lazy != null && lazy.value());
        }

        @Override
        protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
            return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :
                    getResource(this, requestingBeanName));
        }
    }
}

4.2 解析WebService相关的注解和属性注入

WebServiceRefElement是Spring中用于解析WebService相关注解和属性注入的类,源码如下:

public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
        implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {

    /**
     * 解析WebService相关的注解
     */
    private class WebServiceRefElement extends LookupElement {
        private final Class<?> elementType;
        private final String wsdlLocation;

        public WebServiceRefElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) {
            super(member, pd);
            // 获取元素对象上的@WebServiceRef注解
            WebServiceRef resource = ae.getAnnotation(WebServiceRef.class);
            // 获取@WebServiceRef注解的name属性值作为资源名称
            String resourceName = resource.name();
            // 获取@WebServiceRef注解的type属性值作为资源类型
            Class<?> resourceType = resource.type();
            // 根据资源名称是否为空判断当前元素是否有默认名称
            this.isDefaultName = !StringUtils.hasLength(resourceName);
            // 如果当前元素有默认名称
            if (this.isDefaultName) {
                // 获取当前元素对象的名称作用资源名称
                resourceName = this.member.getName();
                // 如果添加注解的当前元素是方法,且方法名以set开头,且资源对象名称不为空
                if (this.member instanceof Method && resourceName.startsWith("set") && resourceName.length() > 3) {
                    // 利用JDK的内省机制,将格式化资源名称(将去掉set之后的名称首字//母小写),是资源名称符合java变量的驼峰命名规则
                    resourceName = Introspector.decapitalize(resourceName.substring(3));
                }
            }
            // 如果@WebServiceRef注解的type属性值不为空
            if (Object.class != resourceType) {
                // 根据注解配置的资源类型值检查资源对象是字段还是方法
                checkResourceType(resourceType);
            }
            // 如果@WebServiceRef注解没有配置type属性
            else {
                // No resource type specified... check field/method.
                // 容器通过JDK的反射机制检查资源对象是字段还是方法类型
                resourceType = getResourceType();
            }
            // 将资源名称赋值给元素的名称
            this.name = resourceName;
            // 为元素设置资源类型
            this.elementType = resourceType;
            // 指定类型的资源可以Service被访问
            if (Service.class.isAssignableFrom(resourceType)) {
                // 设置JNDI的类型
                this.lookupType = resourceType;
            }
            //如果指定类型的资源不能被Service访问
            else {
                // 根据@WebServiceRef注解的value属性值是否是Object,设置JNDI类型
                this.lookupType = resource.value();
            }
            // 获取@WebServiceRef注解的mappedName属性值,设置JNDI名称
            this.mappedName = resource.mappedName();
            // 获取@WebServiceRef注解的wsdlLocation属性值,设置元素的wsdl路径
            this.wsdlLocation = resource.wsdlLocation();
        }

        /**
         * 属性注入
         * @return
         */
        @Override
        protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
            Service service;
            try {
                // 根据JNDI名称和类型获取指定资源对象
                service = (Service) getResource(this, requestingBeanName);
            }
            catch (NoSuchBeanDefinitionException notFound) {
                // Service to be created through generated class.
                // 如果JNDI类型是Service
                if (Service.class == this.lookupType) {
                    throw new IllegalStateException("No resource with name '" + this.name + "' found in context, " +
                            "and no specific JAX-WS Service subclass specified. The typical solution is to either specify " +
                            "a LocalJaxWsServiceFactoryBean with the given name or to specify the (generated) Service " +
                            "subclass as @WebServiceRef(...) value.");
                }
                // 如果元素的wsdl路径不为空
                if (StringUtils.hasLength(this.wsdlLocation)) {
                    try {
                        // 根据wsdl获取构造方法
                        Constructor<?> ctor = this.lookupType.getConstructor(URL.class, QName.class);
                        // 获取元素JDNI类型的@WebServiceClient注解,创建WebService客户端对象
                        WebServiceClient clientAnn = this.lookupType.getAnnotation(WebServiceClient.class);
                        if (clientAnn == null) {
                            throw new IllegalStateException("JAX-WS Service class [" + this.lookupType.getName() +
                                    "] does not carry a WebServiceClient annotation");
                        }
                        // 根据构造方法和wsdl文件WebService实例对象
                        service = (Service) BeanUtils.instantiateClass(ctor,
                                new URL(this.wsdlLocation), new QName(clientAnn.targetNamespace(), clientAnn.name()));
                    }
                    catch (NoSuchMethodException ex) {
                        throw new IllegalStateException("JAX-WS Service class [" + this.lookupType.getName() +
                                "] does not have a (URL, QName) constructor. Cannot apply specified WSDL location [" +
                                this.wsdlLocation + "].");
                    }
                    catch (MalformedURLException ex) {
                        throw new IllegalArgumentException(
                                "Specified WSDL location [" + this.wsdlLocation + "] isn't a valid URL");
                    }
                }
                // 如果元素没有配置wsdl文件路径,则根据JNDI类型创建WebService实例,通过JDK的反射机制,调用合适的构造方法创建实例对象
                else {
                    service = (Service) BeanUtils.instantiateClass(this.lookupType);
                }
            }
            // 根据资源类型创建WebService提供服务的代理对象
            return service.getPort(this.elementType);
        }
    }
}

通过上面的源码分析,我们知道Spring容器在对WebSerice进行注入时,首先通过JNDI查找容器中的实例对象,如果没有找到,则根据wsdl文件实例化WebService对象,如果没有指定wsdl文件的路径,则根据类型利用JDK的反射机制生成WebService实例对象,完成注入.

4.3 EjbRefElement解析EJB相关的注解和属性注入

EjbRefElement是Spring中用于解析EJB相关注解和属性注入的类,源码如下:

public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
        implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {

    /**
     * 解析EJB相关的注解
     */
    private class EjbRefElement extends LookupElement {
        private final String beanName;

        public EjbRefElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) {
            super(member, pd);
            // 获取元素上的@EJB注解
            EJB resource = ae.getAnnotation(EJB.class);
            // 获取@EJB注解的beanName属性值,作为资源Bean名称
            String resourceBeanName = resource.beanName();
            // 获取@EJB注解的name属性值,作为资源名称
            String resourceName = resource.name();
            // 根据资源名称是否为空判断元素是否有默认名称
            this.isDefaultName = !StringUtils.hasLength(resourceName);
            // 如果元素有默认名称
            if (this.isDefaultName) {
                // 获取元素对象名称作用资源名称
                resourceName = this.member.getName();
                // 如果元素是方法,且是以set开头的方法,并且元素名称不为空
                if (this.member instanceof Method && resourceName.startsWith("set") && resourceName.length() > 3) {
                    // 利用JDK内省机制格式化资源名称
                    resourceName = Introspector.decapitalize(resourceName.substring(3));
                }
            }
            // 获取@EJB注解中的beanInterface属性值,作用资源类型
            Class<?> resourceType = resource.beanInterface();
            //如果资源类型不为空
            if (Object.class != resourceType) {
                // 根据资源类型判断资源是字段还是方法
                checkResourceType(resourceType);
            }
            // 如果@EJB注解中没有指定资源类型
            else {
                // 利用JDK反射机制判断资源是字段还是方法类型
                resourceType = getResourceType();
            }
            // 设置元素的Bean名称为@EJB注解中配置的resourceBeanName属性值
            this.beanName = resourceBeanName;
            // 设置元素名称为资源名称 
            this.name = resourceName;
            // 设置JNDI类型为资源类型
            this.lookupType = resourceType;
            // 获取@EJB注解中的mappedName属性值,作为JDNI名称
            this.mappedName = resource.mappedName();
        }

        /**
         * 属性注入
         * @param target
         * @param requestingBeanName
         * @return
         */
        @Override
        protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
            // 如果当前Bean名称不为空
            if (StringUtils.hasLength(this.beanName)) {
                // 如果容器不为null,并且容器中存在指定名称的Bean
                if (beanFactory != null && beanFactory.containsBean(this.beanName)) {
                    // Local match found for explicitly specified local bean name.
                    // 直接从本地容器中获取指定名称的Bean
                    Object bean = beanFactory.getBean(this.beanName, this.lookupType);
                    // 向容器注册Bean名称
                    if (requestingBeanName != null && beanFactory instanceof ConfigurableBeanFactory) {
                        ((ConfigurableBeanFactory) beanFactory).registerDependentBean(this.beanName, requestingBeanName);
                    }
                    // 返回从本地容器中获取到的Bean对象
                    return bean;
                }
                // 如果元素有默认名称,且元素的JNDI名称为空
                else if (this.isDefaultName && !StringUtils.hasLength(this.mappedName)) {
                    throw new NoSuchBeanDefinitionException(this.beanName,
                            "Cannot resolve 'beanName' in local BeanFactory. Consider specifying a general 'name' value instead.");
                }
            }
            // 通过JNDI查找指定名称资源
            return getResource(this, requestingBeanName);
        }
    }
}

从上面对@ResourceWebServiceEJB相关注解解析源码的分析中,我们可以看出,Spring主要使用JDNI查找方式获取这三类注解资源,另外,由源码的“if (this.member instanceof Method&& resourceName.startsWith("set") && resourceName.length() > 3)”判断条件,我们可以看出这三类注解只能添加在字段上,或者set属性方法上,在get属性方法上添加这三类注解将是无法被解析的.

5.RequiredAnnotationBeanPostProcessor

RequiredAnnotationBeanPostProcessor是Spring中用于处理@Required注解的,@Required注解强制要求Bean属性必须被配置,当Spring容器对Bean的属性进行依赖注入时,配置了@Required注解的属性,Spring容器会检查依赖关系是否设置,按照其主要功能分析其主要实现源码:

/**
 * @deprecated as of 5.1, in favor of using constructor injection for required settings
 * (or a custom {@link org.springframework.beans.factory.InitializingBean} implementation)
 */
@Deprecated
public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
        implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {

    /**
     * 注入属性
     */
    @Override
    public PropertyValues postProcessPropertyValues(
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {

        // 如果容器缓存中没有指定Bean名称
        if (!this.validatedBeanNames.contains(beanName)) {
            // 如果指定Bean定义中没有设置skipRequiredCheck属性
            if (!shouldSkip(this.beanFactory, beanName)) {
                List<String> invalidProperties = new ArrayList<>();
                // 遍历所有属性
                for (PropertyDescriptor pd : pds) {
                    // 如果属性添加了@Required注解,且属性集合中不包含指定名称的属性
                    if (isRequiredProperty(pd) && !pvs.contains(pd.getName())) {
                        // 当前属性为无效的属性
                        invalidProperties.add(pd.getName());
                    }
                }
                // 如果无效属性集合不为空
                if (!invalidProperties.isEmpty()) {
                    throw new BeanInitializationException(buildExceptionMessage(invalidProperties, beanName));
                }
            }
            // 将Bean名称缓存到容器中
            this.validatedBeanNames.add(beanName);
        }
        // 返回经过验证的属性值
        return pvs;
    }

    /**
     * 检查给定属性上是否添加了@Required注解
     */
    protected boolean isRequiredProperty(PropertyDescriptor propertyDescriptor) {
        // 获取给定属性的写方法(setter方法)
        Method setter = propertyDescriptor.getWriteMethod();
        // 检查给定属性方法上是否存在指定类型的注解  
        return (setter != null && AnnotationUtils.getAnnotation(setter, getRequiredAnnotationType()) != null);
    }
}

6.PersistenceAnnotationBeanPostProcessor

PersistenceAnnotationBeanPostProcessor是Spring中用于处理JPA相关注解的Bean后置处理器,主要解析和处理@PersistenceUnit@PersistenceContext注解,其主要作用是为JPA的实体管理器工厂(EntityManagerFactory)和实体管理器(EntityManager)注入相应的持久化单元(PersistenceUnit)或持久化上下文(PersistenceContext).按照其主要功能分析其主要实现源码:

6.1 处理和查找持久化元信息

public class PersistenceAnnotationBeanPostProcessor
        implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor,
        MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware, Serializable {

    /**
     * 处理持久化相关属性
     */
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        // 查找给定类中持久化元信息
        InjectionMetadata metadata = findPersistenceMetadata(beanName, bean.getClass(), pvs);
        try {
            // 为Bean注入持久化属性
            metadata.inject(bean, beanName, pvs);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(beanName, "Injection of persistence dependencies failed", ex);
        }
        return pvs;
    }

    /**
     * 查找给定类中的持久化元信息
     */
    private InjectionMetadata findPersistenceMetadata(String beanName, final Class<?> clazz, @Nullable PropertyValues pvs) {
        // Fall back to class name as cache key, for backwards compatibility with custom callers.
        String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
        // 从容器缓存中查找给定类的元信息
        InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
        // 容器缓存中没有给定类的元信息
        if (InjectionMetadata.needsRefresh(metadata, clazz)) {
            synchronized (this.injectionMetadataCache) {
                metadata = this.injectionMetadataCache.get(cacheKey);
                if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                    if (metadata != null) {
                        metadata.clear(pvs);
                    }
                    metadata = buildPersistenceMetadata(clazz);
                    // 向容器中缓存给定类的注入元信息
                    this.injectionMetadataCache.put(cacheKey, metadata);
                }
            }
        }
        // 返回查找到的注入元信息  
        return metadata;
    }

    private InjectionMetadata buildPersistenceMetadata(final Class<?> clazz) {
        // 创建一个存储所有注入元信息的集合
        List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
        Class<?> targetClass = clazz;

        // 递归遍历给定类及其所有非Object类型的基类
        do {
            //创建一个存储当前类注入信息的集合
            final LinkedList<InjectionMetadata.InjectedElement> currElements =
                    new LinkedList<>();

            // 遍历给定类的所有声明字段
            ReflectionUtils.doWithLocalFields(targetClass, field -> {
                // 获取当前字段上的@PersistenceContext注解
                if (field.isAnnotationPresent(PersistenceContext.class) ||
                        // 获取当前字段上的@PersistenceUnit注解
                        field.isAnnotationPresent(PersistenceUnit.class)) {
                    // 持久化注解不支持在静态字段上配置
                    if (Modifier.isStatic(field.getModifiers())) {
                        throw new IllegalStateException("Persistence annotations are not supported on static fields");
                    }
                    // 将配置了持久化注解的字段添加到当前类的注入元信息集合中
                    currElements.add(new PersistenceElement(field, field, null));
                }
            });

            // 遍历给定类的所有声明方法
            ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
                if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                    return;
                }
                // 获取当前方法上的@PersistenceContext注解
                if ((bridgedMethod.isAnnotationPresent(PersistenceContext.class) ||
                        // 获取当前方法上的@PersistenceUnit注解
                        bridgedMethod.isAnnotationPresent(PersistenceUnit.class)) &&
                        // 静态方法上不支持配置持久化注
                        method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                    if (Modifier.isStatic(method.getModifiers())) {
                        throw new IllegalStateException("Persistence annotations are not supported on static methods");
                    }
                    // 持久化注解只能配置了只有一个参数的方法上
                    if (method.getParameterCount() != 1) {
                        throw new IllegalStateException("Persistence annotation requires a single-arg method: " + method);
                    }
                    // 获取当前方法的属性描述符
                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                    // 将配置了持久化注解的方法添加到当前类的注入元信息集合中
                    currElements.add(new PersistenceElement(method, bridgedMethod, pd));
                }
            });

            // 将当前类的注入元信息添加到注入元信息集合中
            elements.addAll(0, currElements);
            // 获取当前类的基类
            targetClass = targetClass.getSuperclass();
        }
        // 当前类的基类不为null,且不是Object,递归注入基类元信息
        while (targetClass != null && targetClass != Object.class);

        return new InjectionMetadata(clazz, elements);
    }
}

6.2 根据持久化单元名称获取持久化上下文、持久化单元和实体管理器工厂

PersistenceAnnotationBeanPostProcessor最重要的核心功能就是根据持久化单元名称获取相应的持久化上下文,持久化单元或者实体管理器工厂,源码如下:

public class PersistenceAnnotationBeanPostProcessor
        implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor,
        MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware, Serializable {

    /**
     * 根据持久化单元名称获取实体管理器工厂
     */
    @Nullable
    protected EntityManagerFactory getPersistenceUnit(@Nullable String unitName) {
        //如果持久化单元不为null
        if (this.persistenceUnits != null) {
            // 获取持久化单元名称
            String unitNameForLookup = (unitName != null ? unitName : "");
            // 如果持久化单元名称为空
            if (unitNameForLookup.isEmpty()) {
                // 将默认的持久化单元名称作为持久化单元名称
                unitNameForLookup = this.defaultPersistenceUnitName;
            }
            // 获取持久化单元的JNDI名称
            String jndiName = this.persistenceUnits.get(unitNameForLookup);
            if (jndiName == null && "".equals(unitNameForLookup) && this.persistenceUnits.size() == 1) {
                // 从持久化单元中获取JNDI名称
                jndiName = this.persistenceUnits.values().iterator().next();
            }
            if (jndiName != null) {
                try {
                    // 查找指定JNDI名称的实体管理器工厂
                    return lookup(jndiName, EntityManagerFactory.class);
                }
                catch (Exception ex) {
                    throw new IllegalStateException("Could not obtain EntityManagerFactory [" + jndiName + "] from JNDI", ex);
                }
            }
        }
        return null;
    }

    /**
     * 查找给定持久化单元名称的实体管理器
     */
    @Nullable
    protected EntityManager getPersistenceContext(@Nullable String unitName, boolean extended) {
        // 获取持久化上下文
        Map<String, String> contexts = (extended ? this.extendedPersistenceContexts : this.persistenceContexts);
        // 持久化上下文不为null
        if (contexts != null) {
            String unitNameForLookup = (unitName != null ? unitName : "");
            if (unitNameForLookup.isEmpty()) {
                unitNameForLookup = this.defaultPersistenceUnitName;
            }
            // 从持久化上下文中获取给定持久化单元名称的JNDI
            String jndiName = contexts.get(unitNameForLookup);
            if (jndiName == null && "".equals(unitNameForLookup) && contexts.size() == 1) {
                jndiName = contexts.values().iterator().next();
            }
            if (jndiName != null) {
                try {
                    // 查找指定JNDI名称的实体管理器
                    return lookup(jndiName, EntityManager.class);
                }
                catch (Exception ex) {
                    throw new IllegalStateException("Could not obtain EntityManager [" + jndiName + "] from JNDI", ex);
                }
            }
        }
        return null;
    }

    /**
     * 从Spring容器中查找给定名称的实体管理器工厂
     */
    protected EntityManagerFactory findEntityManagerFactory(@Nullable String unitName, @Nullable String requestingBeanName)
            throws NoSuchBeanDefinitionException {

        // 获取持久化单元名称
        String unitNameForLookup = (unitName != null ? unitName : "");
        // 如果持久化单元名称为空,则将容器默认持久化单元名称作用持久化单元名称
        if (unitNameForLookup.isEmpty()) {
            unitNameForLookup = this.defaultPersistenceUnitName;
        }
        // 如果持久化单元名称不为空,查找给定持久化单元名称的实体管理器工厂
        if (!unitNameForLookup.isEmpty()) {
            return findNamedEntityManagerFactory(unitNameForLookup, requestingBeanName);
        }
        // 如果持久化单元名称为空,获取容器中默认的实体管理器工厂
        else {
            return findDefaultEntityManagerFactory(requestingBeanName);
        }
    }

    /**
     * 查找给定持久化单元名称的实体管理器工厂
     */
    protected EntityManagerFactory findNamedEntityManagerFactory(String unitName, @Nullable String requestingBeanName)
            throws NoSuchBeanDefinitionException {
        Assert.state(this.beanFactory != null, "ListableBeanFactory required for EntityManagerFactory bean lookup");

        // 从Spring所有容器中查找给定名称的实体管理器工厂对象
        EntityManagerFactory emf = EntityManagerFactoryUtils.findEntityManagerFactory(this.beanFactory, unitName);
        // 将持久化单元名称和查找到的实体管理器工厂对象向Spring容器注册
        if (requestingBeanName != null && this.beanFactory instanceof ConfigurableBeanFactory) {
            ((ConfigurableBeanFactory) this.beanFactory).registerDependentBean(unitName, requestingBeanName);
        }
        return emf;
    }

    /**
     * 获取容器默认的实体管理器工厂
     * Find a single default EntityManagerFactory in the Spring application context.
     * @return the default EntityManagerFactory
     * @throws NoSuchBeanDefinitionException if there is no single EntityManagerFactory in the context
     */
    protected EntityManagerFactory findDefaultEntityManagerFactory(@Nullable String requestingBeanName)
            throws NoSuchBeanDefinitionException {

        Assert.state(this.beanFactory != null, "ListableBeanFactory required for EntityManagerFactory bean lookup");

        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            // Fancy variant with dependency registration
            ConfigurableListableBeanFactory clbf = (ConfigurableListableBeanFactory) this.beanFactory;
            // 从Spring所有容器中查找给定类型的Bean的名称
            NamedBeanHolder<EntityManagerFactory> emfHolder = clbf.resolveNamedBean(EntityManagerFactory.class);
            if (requestingBeanName != null) {
                // 将查找到的实体管理器工厂Bean和持久化单元名称向Spring容器注册
                clbf.registerDependentBean(emfHolder.getBeanName(), requestingBeanName);
            }
            return emfHolder.getBeanInstance();
        }
        else {
            // Plain variant: just find a default bean
            return this.beanFactory.getBean(EntityManagerFactory.class);
        }
    }
}

6.3 PersistenceElement

PersistenceElement是Spring中用于解析持久化相关注解,并提供相应的实体管理器工厂或者实体管理器,PersistenceElement解析持久化相关注解的源码如下:

public class PersistenceAnnotationBeanPostProcessor
        implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor,
        MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware, Serializable {

    /**
     * 解析持久化注解
     */
    private class PersistenceElement extends InjectionMetadata.InjectedElement {
        public PersistenceElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) {
            super(member, pd);
            // 获取当前元素对象的@PersistenceContext注解
            PersistenceContext pc = ae.getAnnotation(PersistenceContext.class);
            // 获取当前元素对象的@PersistenceUnit注解
            PersistenceUnit pu = ae.getAnnotation(PersistenceUnit.class);
            // 资源类型为实体管理器
            Class<?> resourceType = EntityManager.class;
            // 如果元素配置的持久化上下文不为null
            if (pc != null) {
                // 如果元素配置的持久化单元也不为null
                if (pu != null) {
                    // 持久化上下文和持久化单元只能二选一,不能同时配置
                    throw new IllegalStateException("Member may only be annotated with either " +
                            "@PersistenceContext or @PersistenceUnit, not both: " + member);
                }
                Properties properties = null;
                // 获取持久化上下文的属性
                PersistenceProperty[] pps = pc.properties();
                // 如果持久化上下文属性不为空
                if (!ObjectUtils.isEmpty(pps)) {
                    properties = new Properties();
                    // 将持久化上下文的属性名称和属性值保存到属性集合中
                    for (PersistenceProperty pp : pps) {
                        properties.setProperty(pp.name(), pp.value());
                    }
                }
                // 设置元素的持久化单元名称
                this.unitName = pc.unitName();
                // 设置元素的持久化类型为实体管理器(EntityManager)
                this.type = pc.type();
                this.synchronizedWithTransaction = SynchronizationType.SYNCHRONIZED.equals(pc.synchronization());
                //设置元素的持久化属性
                this.properties = properties;
            }
            // 如果持久化上下文为null
            else {
                // 持久化资源类型为实体管理器工厂
                resourceType = EntityManagerFactory.class;
                this.unitName = pu.unitName();
            }
            // 检查给定的持久化资源类型是字段还是方法类型
            checkResourceType(resourceType);
        }
    }
}

从上面的源码我们可以看到,当配置了持久化上下文时,容器会自动选择实体管理器作用持久化资源类型,如果配置了持久化单元时,选择实体管理器工厂作为持久化资源类型.

6.4 获取并注入持久化资源

public class PersistenceAnnotationBeanPostProcessor
        implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor,
        MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware, Serializable {

    /**
     * 解析持久化注解
     */
    private class PersistenceElement extends InjectionMetadata.InjectedElement {
        /**
         * 获取并注入持久化资源
         */
        @Override
        protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
            // 持久化资源类型不为null,创建实体管理器
            if (this.type != null) {
                return (this.type == PersistenceContextType.EXTENDED ?
                        resolveExtendedEntityManager(target, requestingBeanName) :
                        resolveEntityManager(requestingBeanName));
            }
            // 持久化资源类型为null,创建实体管理器工厂
            else {
                return resolveEntityManagerFactory(requestingBeanName);
            }
        }

        /**
         * 创建扩展的实体管理器
         */
        private EntityManager resolveExtendedEntityManager(Object target, @Nullable String requestingBeanName) {
            // 以持久化单元名称作为JNDI名称获取持久化上下文作为实体管理器
            EntityManager em = getPersistenceContext(this.unitName, true);
            // 如果根据JNDI获取到的持久化上下文为nul
            if (em == null) {
                // 以持久化单元名称作为JNDI名称获取实体管理器工厂
                EntityManagerFactory emf = getPersistenceUnit(this.unitName);
                // 没有获取到指定JNDI名称的实体管理器工厂
                if (emf == null) {
                    // 根据持久化单元名称向Spring容器查找指定名称的实体管理器工厂
                    emf = findEntityManagerFactory(this.unitName, requestingBeanName);
                }
                // 根据实体管理器工厂和持久化属性创建一个容器管理的实体管理器
                em = ExtendedEntityManagerCreator.createContainerManagedEntityManager(
                        emf, this.properties, this.synchronizedWithTransaction);
            }
            // 创建实体管理器代理委派调用的实体管理器
            if (em instanceof EntityManagerProxy && beanFactory != null && requestingBeanName != null &&
                    beanFactory.containsBean(requestingBeanName) && !beanFactory.isPrototype(requestingBeanName)) {
                extendedEntityManagersToClose.put(target, ((EntityManagerProxy) em).getTargetEntityManager());
            }
            return em;
        }

        /**
         * 创建实体管理器
         */
        private EntityManager resolveEntityManager(@Nullable String requestingBeanName) {
            // 以持久化单元名称作为JNDI名称获取持久化上下文作为实体管理器
            EntityManager em = getPersistenceContext(this.unitName, false);
            // 如果根据JNDI获取到的持久化上下文为null
            if (em == null) {
                // 以持久化单元名称作为JNDI名称获取实体管理器工厂
                EntityManagerFactory emf = getPersistenceUnit(this.unitName);
                // 没有获取到指定JNDI名称的实体管理器工厂
                if (emf == null) {
                    // 根据持久化单元名称向Spring容器查找指定名称的实体管理器工厂
                    emf = findEntityManagerFactory(this.unitName, requestingBeanName);
                }
                // 创建一个共享事务管理的实体管理器代理
                if (emf instanceof EntityManagerFactoryInfo &&
                        ((EntityManagerFactoryInfo) emf).getEntityManagerInterface() != null) {
                    // 根据JPA实现提供商类型创建相应的实体管理器
                    em = SharedEntityManagerCreator.createSharedEntityManager(
                            emf, this.properties, this.synchronizedWithTransaction);
                }
                else {
                    // 根据持久化注解配置的持久化资源类型创建实体管理器
                    em = SharedEntityManagerCreator.createSharedEntityManager(
                            emf, this.properties, this.synchronizedWithTransaction, getResourceType());
                }
            }
            return em;
        }

        /**
         * 创建实体管理器工厂
         */
        private EntityManagerFactory resolveEntityManagerFactory(@Nullable String requestingBeanName) {
            // 以持久化单元名称作为JNDI名称获取实体管理器工厂
            EntityManagerFactory emf = getPersistenceUnit(this.unitName);
            // 没有获取到指定JNDI名称的实体管理器工厂
            if (emf == null) {
                // 根据持久化单元名称向Spring容器查找指定名称的实体管理器工厂  
                emf = findEntityManagerFactory(this.unitName, requestingBeanName);
            }
            return emf;
        }
    }
}

Spring中还有其他处理注解的Bean后置处理器,其基本的实现原理与上面分析的这4个最常用的注解Bean后置处理器类似,注解其实也没什么神秘的,和XML配置文件类似都是一种配置的方式而已,只不过利用JDK的反射机制,在编译时或者运行时动态获取所配置的信息而已,注解本身只是个标识,注解的真正意义在于通过注解标识获取注解所在对象的信息以及注解中配置的信息.

Spring的注解方式只是简化了XML配置文件,可以在读入Bean定义资源时可以动态扫描给定的路径,在解析和依赖注入时,XML方式配置的Bean,Spring需要解析XML文件,注解方式配置的Bean,Spring需要通过JDK的反射机制获取注解配置的信息.

results matching ""

    No results matching ""