Spring对注解(Annotation)处理源码分析2——解析和注入注解配置的资源

 

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

2.Spring中处理注解的Bean后置处理器:

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

 

 

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

下面将具体介绍这4个注解后置处理器。

:

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

(1).的构造方法:

AutowiredAnnotationBeanPostProcessor只有一个的构造方法,其源码如下:

 

 

(2).为指定类选择其合适的构造方法:

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

 

 

(3).AutowiredAnnotationBeanPostProcessor对方法和属性的依赖注入:

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

 

 

(4).AutowiredAnnotationBeanPostProcessor对字段和方法的注入:

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

 

 

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

 

 

beanFactory.resolveDependencyregisterDependentBeans方法我们在Spring容器依赖注入源码分析中已经分析过,这里就不再具体分析。

后置处理器主要解析autowire相关的注解,即@Autowire@Value等。

 

4.

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

(1).静态初始化块和构造函数:

 

 

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

 

(2).CommonAnnotationBeanPostProcessor对属性值的查找:

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

 

 

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

(3).根据给定名称或者类型获取资源对象:

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

 

 

(4).@ResourceWebServiceEJB相关注解的解析和属性注入:

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

a.ResourceElement解析@Resource注解和属性注入:

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

 

 

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

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

 

 

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

c.EjbRefElement解析EJB相关的注解和属性注入:

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

 

 

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

5.RequiredAnnotationBeanPostProcessor

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

 

 

6.

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

(1).处理和查找持久化元信息:

 

 

(2).根据持久化单元名称获取持久化上下文、持久化单元和实体管理器工厂:

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

 

 

(3).

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

 

 

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

(4).获取并注入持久化资源:

PersistenceElement类对持久化注解解析获取到基本的持久化信息之后,就可以根据注解配置的持久化信息获取并注入相应的持久化资源,源码如下:

 

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

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

展开阅读全文

没有更多推荐了,返回首页