Spring对注解(Annotation)处理源码分析2——解析和注入注解配置的资源 .
<context:annotation-config>< context:component-scan >?
?
public AutowiredAnnotationBeanPostProcessor() {//后置处理器将处理@Autowire注解this.autowiredAnnotationTypes.add(Autowired.class);//后置处理器将处理@Value注解this.autowiredAnnotationTypes.add(Value.class);//获取当前类的类加载器ClassLoader cl = AutowiredAnnotationBeanPostProcessor.class.getClassLoader();try {//后置处理器将处理javax.inject.Inject JSR-330注解this.autowiredAnnotationTypes.add((Class<? extends Annotation>) cl.loadClass("javax.inject.Inject"));logger.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");}catch (ClassNotFoundException ex) {// JSR-330 API not available - simply skip.}} ?
?
//为自动依赖注入装配Bean选择合适的构造方法public Constructor[] determineCandidateConstructors(Class beanClass, String beanName) throws BeansException {//首先从容器的缓存中查找是否有指定Bean的构造方法Constructor[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);//容器缓存中没有给定类的构造方法if (candidateConstructors == null) {//线程同步以确保容器中数据一致性synchronized (this.candidateConstructorsCache) {candidateConstructors = this.candidateConstructorsCache.get(beanClass);if (candidateConstructors == null) {//通过JDK反射机制,获取指定类的中所有声明的构造方法Constructor[] rawCandidates = beanClass.getDeclaredConstructors();//存放候选构造方法的集合List<Constructor> candidates = new ArrayList<Constructor>(rawCandidates.length);//autowire注解中required属性指定的构造方法Constructor requiredConstructor = null;//默认的构造方法Constructor defaultConstructor = null;//遍历所有的构造方法,检查是否添加了autowire注解,以及是否//指定了required属性for (Constructor<?> candidate : rawCandidates) {//获取指定类中所有关于autowire的注解(Annotation)Annotation annotation = findAutowiredAnnotation(candidate);//如果指定类中有关于antowire的注解if (annotation != null) {//如果antowire注解中指定了required属性if (requiredConstructor != null) {throw new BeanCreationException("Invalid autowire-marked constructor: " + candidate +". Found another constructor with 'required' Autowired annotation: " +requiredConstructor);}//如果autowire注解的参数列表为空if (candidate.getParameterTypes().length == 0) {throw new IllegalStateException("Autowired annotation requires at least one argument: " + candidate);}//获取autowire注解中required属性值boolean required = determineRequiredStatus(annotation);//如果获取到autowire注解中required的属性值if (required) {//如果候选构造方法集合不为空if (!candidates.isEmpty()) {throw new BeanCreationException("Invalid autowire-marked constructors: " + candidates +". Found another constructor with 'required' Autowired annotation: " +requiredConstructor);}//当前的构造方法就是required属性所配置的构造方法requiredConstructor = candidate;}//将当前的构造方法添加到哦啊候选构造方法集合中candidates.add(candidate);} //如果类中没有autowire的相关注解,并且构造方法参数列表为空else if (candidate.getParameterTypes().length == 0) {//当前的构造方法是默认构造方法defaultConstructor = candidate;}}//如果候选构造方法集合不为空if (!candidates.isEmpty()) {//如果所有的构造方法都没有配置required属性,且有默认构造方法if (requiredConstructor == null && defaultConstructor != null) {//将默认构造方法添加到候选构造方法列表candidates.add(defaultConstructor);}//将候选构造方法集合转换为数组candidateConstructors = candidates.toArray(new Constructor[candidates.size()]);}//如果候选构造方法集合为空,则创建一个空的数组else {candidateConstructors = new Constructor[0];}//将类的候选构造方法集合存放到容器的缓存中this.candidateConstructorsCache.put(beanClass, candidateConstructors);}}}//返回指定类的候选构造方法数组,如果没有返回nullreturn (candidateConstructors.length > 0 ? candidateConstructors : null);} ?
?
//处理类中的属性public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {//获取指定类中autowire相关注解的元信息InjectionMetadata metadata = findAutowiringMetadata(bean.getClass());try {//对Bean的属性进行自动注入metadata.inject(bean, beanName, pvs);}catch (Throwable ex) {throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);}return pvs;}//处理对象的注入public void processInjection(Object bean) throws BeansException {//获取给定Bean的Class对象Class<?> clazz = bean.getClass();//获取给定类中autowire相关注解元信息InjectionMetadata metadata = findAutowiringMetadata(clazz);try {//对Bean对象进行自动注入metadata.inject(bean, null, null);}catch (Throwable ex) {throw new BeanCreationException("Injection of autowired dependencies failed for class [" + clazz + "]", ex);}}//获取给定类的autowire相关注解元信息private InjectionMetadata findAutowiringMetadata(Class clazz) {//首先从容器中查找是否有给定类的autowire相关注解元信息InjectionMetadata metadata = this.injectionMetadataCache.get(clazz);if (metadata == null) {synchronized (this.injectionMetadataCache) {metadata = this.injectionMetadataCache.get(clazz);if (metadata == null) {//解析给定类autowire相关注解元信息metadata = buildAutowiringMetadata(clazz);//将得到的给定类autowire相关注解元信息存储在容器缓存中this.injectionMetadataCache.put(clazz, metadata);}}}return metadata;}//解析给定类autowire相关注解元信息private InjectionMetadata buildAutowiringMetadata(Class clazz) {//创建一个存放注解元信息的集合LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();Class<?> targetClass = clazz;//递归遍历当前类及其所有基类,解析全部注解元信息do {//创建一个存储当前正在处理类注解元信息的集合LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>();//利用JDK反射机制获取给定类中所有的声明字段,获取字段上的注解信息for (Field field : targetClass.getDeclaredFields()) {//获取给定字段上的注解Annotation annotation = findAutowiredAnnotation(field);if (annotation != null) {//如果给定字段是静态的(Static),则直接遍历下一个字段if (Modifier.isStatic(field.getModifiers())) {if (logger.isWarnEnabled()) {logger.warn("Autowired annotation is not supported on static fields: " + field);}continue;}//判断注解的required属性值是否有效boolean required = determineRequiredStatus(annotation);//将当前字段元信息封装,添加在返回的集合中currElements.add(new AutowiredFieldElement(field, required));}}//利用JDK反射机制获取给定类中所有的声明方法,获取方法上的注解信息for (Method method : targetClass.getDeclaredMethods()) {//获取给定方法上的所有注解Annotation annotation = findAutowiredAnnotation(method);if (annotation != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {//如果方法是静态的,则直接遍历下一个方法if (Modifier.isStatic(method.getModifiers())) {if (logger.isWarnEnabled()) {logger.warn("Autowired annotation is not supported on static methods: " + method);}continue;}//如果方法的参数列表为空if (method.getParameterTypes().length == 0) {if (logger.isWarnEnabled()) {logger.warn("Autowired annotation should be used on methods with actual parameters: " + method);}}//判断注解的required属性值是否有效boolean required = determineRequiredStatus(annotation);//获取当前方法的属性描述符,即方法是可读的(readable)getter方法,//还是可写的(writeable)setter方法PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);//将方法元信息封装添加到返回的元信息集合中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);}//获取给定对象的autowire相关注解private Annotation findAutowiredAnnotation(AccessibleObject ao) {//遍历所有autowire相关的注解:@Autowire、@Value以及JSR-330等for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {//获取给定对象上的指定类型的注解Annotation annotation = ao.getAnnotation(type);if (annotation != null) {return annotation;}}return null;}?
?
//对字段进行注入protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {//获取注入元素对象Field field = (Field) this.member;try {Object value;//如果当前对象在容器中被缓存if (this.cached) {//根据Bean名称解析缓存中的字段值value = resolvedCachedArgument(beanName, this.cachedFieldValue);}//如果当前对象没有被容器缓存else {//创建一个字段依赖描述符DependencyDescriptor descriptor = new DependencyDescriptor(field, this.required);Set<String> autowiredBeanNames = new LinkedHashSet<String>(1);//获取容器中的类型转换器TypeConverter typeConverter = beanFactory.getTypeConverter();//根据容器中Bean定义,解析指定的依赖关系,获取依赖对象value = beanFactory.resolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter);//线程同步,确保容器中数据一致性synchronized (this) {//如果当前对象没有被容器缓存if (!this.cached) {//获取到了当前对象的依赖对象,并且required属性为trueif (value != null || this.required) {this.cachedFieldValue = descriptor;//为指定Bean注册依赖BeanregisterDependentBeans(beanName, autowiredBeanNames);if (autowiredBeanNames.size() == 1) {String autowiredBeanName = autowiredBeanNames.iterator().next();//如果容器中有指定名称的Bean对象if (beanFactory.containsBean(autowiredBeanName)) {//依赖对象类型和字段类型匹配,默认按类型注入if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {//创建一个依赖对象的引用,同时缓存this.cachedFieldValue = new RuntimeBeanReference(autowiredBeanName);}}}}//如果获取的依赖关系为null,且获取required属性为falseelse {//将字段值的缓存设置为nullthis.cachedFieldValue = null;}//容器已经对当前字段的值缓存this.cached = true;}}}//如果字段依赖值不为nullif (value != null) {//显式使用JDK的反射机制,设置自动的访问控制权限为允许访问ReflectionUtils.makeAccessible(field);//为Bean对象的字段设置值field.set(bean, value);}}catch (Throwable ex) {throw new BeanCreationException("Could not autowire field: " + field, ex);}}}?
?
//对方法进行注入protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {//如果属性被显式设置为skip,则不进行注入if (checkPropertySkipping(pvs)) {return;}//获取注入元素对象Method method = (Method) this.member;try {Object[] arguments;//如果容器对当前方法缓存if (this.cached) {//获取缓存中指定Bean名称的方法参数arguments = resolveCachedArguments(beanName);}//如果没有缓存else {//获取方法的参数列表Class[] paramTypes = method.getParameterTypes();//创建一个存放方法参数的数组arguments = new Object[paramTypes.length];DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length];Set<String> autowiredBeanNames = new LinkedHashSet<String>(paramTypes.length);//获取容器的类型转换器TypeConverter typeConverter = beanFactory.getTypeConverter();for (int i = 0; i < arguments.length; i++) {//创建方法参数对象MethodParameter methodParam = new MethodParameter(method, i);//解析方法的输入参数和返回值类型GenericTypeResolver.resolveParameterType(methodParam, bean.getClass());//为方法参数创建依赖描述符descriptors[i] = new DependencyDescriptor(methodParam, this.required);//根据容器中Bean定义解析依赖关系,获取方法参数依赖对象arguments[i] = beanFactory.resolveDependency(descriptors[i], beanName, autowiredBeanNames, typeConverter);//如果容器解析的方法参数为null,且方法required属性为falseif (arguments[i] == null && !this.required) {//设置方法的参数列表为nullarguments = null;break;}}//线程同步,以确保容器中数据一致性synchronized (this) {//如果当前方法没有被容器缓存if (!this.cached) {//如果方法的参数列表不为空if (arguments != null) {//为容器中缓存方法参数的对象赋值this.cachedMethodArguments = new Object[arguments.length];for (int i = 0; i < arguments.length; i++) {this.cachedMethodArguments[i] = descriptors[i];}//为指定Bean注册依赖BeanregisterDependentBeans(beanName, autowiredBeanNames);//如果依赖对象集合大小等于方法参数个数if (autowiredBeanNames.size() == paramTypes.length) {Iterator<String> it = autowiredBeanNames.iterator();//为方法参数设置依赖对象for (int i = 0; i < paramTypes.length; i++) {String autowiredBeanName = it.next();//如果容器中存在指定名称的Bean对象if (beanFactory.containsBean(autowiredBeanName)) {//如果参数类型和依赖对象类型匹配if (beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {//创建一个依赖对象的引用,复制给方法相应的参数this.cachedMethodArguments[i] = new RuntimeBeanReference(autowiredBeanName);}}}}}//如果方法参数列表为null,则设置容器对该方法参数的缓存为nullelse {this.cachedMethodArguments = null;}//设置容器已经对该方法缓存this.cached = true;}}}//如果方法参数依赖对象不为nullif (arguments != null) {//使用JDK的反射机制,显式设置方法的访问控制权限为允许访问ReflectionUtils.makeAccessible(method);//调用Bean的指定方法method.invoke(bean, arguments);}}catch (InvocationTargetException ex) {throw ex.getTargetException();}catch (Throwable ex) {throw new BeanCreationException("Could not autowire method: " + method, ex);}}?
?
//WebService关于JAX-WS的相关注解private static Class<? extends Annotation> webServiceRefClass = null;//EJB相关的注解private static Class<? extends Annotation> ejbRefClass = null;//静态初始化块static {//获取当前类的类加载器ClassLoader cl = CommonAnnotationBeanPostProcessor.class.getClassLoader();try {//使用类加载器加载WebService相关的类webServiceRefClass = (Class) cl.loadClass("javax.xml.ws.WebServiceRef");}catch (ClassNotFoundException ex) {webServiceRefClass = null;}try {//使用类加载器加载EJB相关的类ejbRefClass = (Class) cl.loadClass("javax.ejb.EJB");}catch (ClassNotFoundException ex) {ejbRefClass = null;}} //构造方法public CommonAnnotationBeanPostProcessor() {setOrder(Ordered.LOWEST_PRECEDENCE - 3);//设置初始的注解类型为@PostConstructsetInitAnnotationType(PostConstruct.class);//设置消耗的注解为@ PreDestroysetDestroyAnnotationType(PreDestroy.class);//当使用@Resource注解时,忽略JAX-WS的资源类型ignoreResourceType("javax.xml.ws.WebServiceContext");}?
?
//处理属性值public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {//获取@Resource注解中配置的属性值元数据InjectionMetadata metadata = findResourceMetadata(bean.getClass());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(final Class clazz) {//首先从容器缓存中查找InjectionMetadata metadata = this.injectionMetadataCache.get(clazz);//缓存中没有给定类的注解元信息数据if (metadata == null) {//线程同步,以确保容器中数据一致synchronized (this.injectionMetadataCache) {metadata = this.injectionMetadataCache.get(clazz);if (metadata == null) {//创建一个用于存放注解元数据的集合LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();Class<?> targetClass = clazz;//递归地的解析给定类及其所有基类的注解元信息do {//创建一个存放当前类注解元数据的集合LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>(); //遍历给定类中所有的字段,查找符合的注解for (Field field : targetClass.getDeclaredFields()) {//如果字段上配置了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, 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, 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 (!ignoredResourceTypes.contains(field.getType().getName())) {currElements.add(new ResourceElement(field, null));}}}//遍历给定类中的所有方法,查找相关的注解for (Method method : targetClass.getDeclaredMethods()) {//如果方法上配置了WebService相关的注解if (webServiceRefClass != null && method.isAnnotationPresent(webServiceRefClass) &&method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {//如方法是静态的,则注解不支持静态方法if (Modifier.isStatic(method.getModifiers())) {throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods");}//如果方法参数个数不等于1if (method.getParameterTypes().length != 1) {throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);}//获取方法的属性描述PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);//将当前方法对象和方法属性描述封装为WebService引用元素currElements.add(new WebServiceRefElement(method, pd));}//如果方法上配置了EJB相关的注解else if (ejbRefClass != null && method.isAnnotationPresent(ejbRefClass) &&method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {if (Modifier.isStatic(method.getModifiers())) {throw new IllegalStateException("@EJB annotation is not supported on static methods");}if (method.getParameterTypes().length != 1) {throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method);}PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);currElements.add(new EjbRefElement(method, pd));}//如果方法上配置了@Resource注解else if (method.isAnnotationPresent(Resource.class) &&method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {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 (!ignoredResourceTypes.contains(paramTypes[0].getName())) {PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);currElements.add(new ResourceElement(method, pd));}}}//将当前类注解元信息存放到注解元信息集合中elements.addAll(0, currElements);//获取当前对象的基类targetClass = targetClass.getSuperclass();}//如果基类不为null,且基类不是Objectwhile (targetClass != null && targetClass != Object.class);metadata = new InjectionMetadata(clazz, elements);//缓存给定类的注解元信息this.injectionMetadataCache.put(clazz, metadata);}}}return metadata;}?
?
//根据给定名称或者类型获取资源对象protected Object getResource(LookupElement element, String requestingBeanName) throws BeansException {//如果注解对象元素的mappedName属性不为空if (StringUtils.hasLength(element.mappedName)) {//根据JNDI名称和类型去Spring的JNDI容器中获取Beanreturn this.jndiFactory.getBean(element.mappedName, element.lookupType);}//如果该后置处理器的alwaysUseJndiLookup属性值为trueif (this.alwaysUseJndiLookup) {//从Spring的JNDI容器中查找指定JDNI名称和类型的Beanreturn 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, String requestingBeanName)throws BeansException {Object resource;Set<String> autowiredBeanNames;String name = element.name;if (this.fallbackToDefaultTypeMatch && element.isDefaultName &&factory instanceof AutowireCapableBeanFactory && !factory.containsBean(name)) {autowiredBeanNames = new LinkedHashSet<String>();//根据容器中Bean定义解析给定的依赖关系,将依赖以资源对象返回resource = ((AutowireCapableBeanFactory) factory).resolveDependency(element.getDependencyDescriptor(), requestingBeanName, autowiredBeanNames, null);}//根据给定JDNI名称和类型从Spring的JDNI容器查找资源else {resource = factory.getBean(name, element.lookupType);autowiredBeanNames = Collections.singleton(name);}//为指定的Bean注册依赖的Beanif (factory instanceof ConfigurableBeanFactory) {ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory) factory;for (String autowiredBeanName : autowiredBeanNames) {beanFactory.registerDependentBean(autowiredBeanName, requestingBeanName);}}return resource;}?
?
//解析@Resource注解protected void initAnnotation(AnnotatedElement ae) {//获取元素对象的@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 (beanFactory instanceof ConfigurableBeanFactory){//解析给定的对象名的内嵌值做为资源名称resourceName = ((ConfigurableBeanFactory) beanFactory).resolveEmbeddedValue(resourceName);}//如果注解配置的资源类型不为空,且不说Object类型if (resourceType != null && !Object.class.equals(resourceType)) {//检查资源类型是字段还是方法checkResourceType(resourceType);}else {//如果注解中没有配置资源类型,则利用JDK反射机制判断是字段还是方法resourceType = getResourceType();}//设置当前注解元素的资源名称this.name = resourceName;//设置当前注解元素的JNDI类型this.lookupType = resourceType;//获取@Resource注解的mappedName属性值,设置当前注解元素的JNDI名称this.mappedName = resource.mappedName();//获取@Resource注解的shareable属性值,设置当前注解元素是否在容器中共享this.shareable = resource.shareable();}//注入属性protected Object getResourceToInject(Object target, String requestingBeanName) {//调用我们在(3)中分析的源码,注入依赖的资源对象return getResource(this, requestingBeanName);}?
?
//解析WebService相关的注解protected void initAnnotation(AnnotatedElement ae) {//获取元素对象上的@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 (resourceType != null && !Object.class.equals(resourceType)) {//根据注解配置的资源类型值检查资源对象是字段还是方法checkResourceType(resourceType);}//如果@WebServiceRef注解没有配置type属性else {//容器通过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 = (!Object.class.equals(resource.value()) ? resource.value() : Service.class);}//获取@WebServiceRef注解的mappedName属性值,设置JNDI名称this.mappedName = resource.mappedName();//获取@WebServiceRef注解的wsdlLocation属性值,设置元素的wsdl路径this.wsdlLocation = resource.wsdlLocation();}//属性注入protected Object getResourceToInject(Object target, String requestingBeanName) {Service service;try {//根据JNDI名称和类型获取指定资源对象service = (Service) getResource(this, requestingBeanName);}catch (NoSuchBeanDefinitionException notFound) {//如果JNDI类型是Serviceif (Service.class.equals(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(new Class[] {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);}?
?
//解析EJB相关的注解protected void initAnnotation(AnnotatedElement ae) {//获取元素上的@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();//如果资源类型不为空,且不是Objectif (resourceType != null && !Object.class.equals(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();}//属性注入protected Object getResourceToInject(Object target, String requestingBeanName) {//如果当前Bean名称不为空if (StringUtils.hasLength(this.beanName)) {//如果容器不为null,并且容器中存在指定名称的Beanif (beanFactory != null && beanFactory.containsBean(this.beanName)) {//直接从本地容器中获取指定名称的BeanObject bean = beanFactory.getBean(this.beanName, this.lookupType);//向容器注册Bean名称if (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);}}?
?
//注入属性public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)throws BeansException {//如果容器缓存中没有指定Bean名称if (!this.validatedBeanNames.contains(beanName)) {//如果指定Bean定义中没有设置skipRequiredCheck属性if (!shouldSkip(this.beanFactory, beanName)) {List<String> invalidProperties = new ArrayList<String>();//遍历所有属性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);}?
?
//处理持久化相关属性public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {//查找给定类中持久化元信息InjectionMetadata metadata = findPersistenceMetadata(bean.getClass());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(final Class clazz) {//首先从容器缓存中查找给定类的元信息InjectionMetadata metadata = this.injectionMetadataCache.get(clazz);//容器缓存中没有给定类的元信息if (metadata == null) {//线程同步,以确保容器中数据的一致性synchronized (this.injectionMetadataCache) {metadata = this.injectionMetadataCache.get(clazz);if (metadata == null) {//创建一个存储所有注入元信息的集合LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();Class<?> targetClass = clazz;//递归遍历给定类及其所有非Object类型的基类do {//创建一个存储当前类注入信息的集合LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>(); //遍历给定类的所有声明字段for (Field field : targetClass.getDeclaredFields()) {//获取当前字段上的@PersistenceContext注解PersistenceContext pc = field.getAnnotation(PersistenceContext.class);//获取当前字段上的@PersistenceUnit注解PersistenceUnit pu = field.getAnnotation(PersistenceUnit.class);//当前字段上配置了@PersistenceContext或者@PersistenceUnit注解if (pc != null || pu != null) {//持久化注解不支持在静态字段上配置if (Modifier.isStatic(field.getModifiers())) {throw new IllegalStateException("Persistence annotations are not supported on static fields");}//将配置了持久化注解的字段添加到当前类的注入元信息集合中currElements.add(new PersistenceElement(field, null));}}//遍历给定类的所有声明方法for (Method method : targetClass.getDeclaredMethods()) {//获取当前方法上的@PersistenceContext注解PersistenceContext pc = method.getAnnotation(PersistenceContext.class);//获取当前方法上的@PersistenceUnit注解PersistenceUnit pu = method.getAnnotation(PersistenceUnit.class);//当前方法上配置了@PersistenceContext或者@PersistenceUnit注解if (pc != null || pu != null &&//静态方法上不支持配置持久化注解method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {if (Modifier.isStatic(method.getModifiers())) {throw new IllegalStateException("Persistence annotations are not supported on static methods");} //持久化注解只能配置了只有一个参数的方法上if (method.getParameterTypes().length != 1) {throw new IllegalStateException("Persistence annotation requires a single-arg method: " + method);}//获取当前方法的属性描述符PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);//将配置了持久化注解的方法添加到当前类的注入元信息集合中currElements.add(new PersistenceElement(method, pd));}}//将当前类的注入元信息添加到注入元信息集合中elements.addAll(0, currElements);//获取当前类的基类targetClass = targetClass.getSuperclass();}//当前类的基类不为null,且不是Object,递归注入基类元信息while (targetClass != null && targetClass != Object.class);metadata = new InjectionMetadata(clazz, elements);//向容器中缓存给定类的注入元信息this.injectionMetadataCache.put(clazz, metadata);}}}//返回查找到的注入元信息return metadata;}?
?
//根据持久化单元名称获取实体管理器工厂protected EntityManagerFactory getPersistenceUnit(String unitName) {//如果持久化单元不为nullif (this.persistenceUnits != null) {//获取持久化单元名称String unitNameForLookup = (unitName != null ? unitName : "");//如果持久化单元名称为空if ("".equals(unitNameForLookup)) {//将默认的持久化单元名称作为持久化单元名称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;}//查找给定持久化单元名称的实体管理器protected EntityManager getPersistenceContext(String unitName, boolean extended) {//获取持久化上下文Map<String, String> contexts = (extended ? this.extendedPersistenceContexts : this.persistenceContexts);//持久化上下文不为nullif (contexts != null) {String unitNameForLookup = (unitName != null ? unitName : "");if ("".equals(unitNameForLookup)) {unitNameForLookup = this.defaultPersistenceUnitName;}//从持久化上下文中获取给定持久化单元名称的JNDIString 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(String unitName, String requestingBeanName)throws NoSuchBeanDefinitionException {//当前Spring容器为nullif (this.beanFactory == null) {throw new IllegalStateException("ListableBeanFactory required for EntityManagerFactory bean lookup");}//获取持久化单元名称String unitNameForLookup = (unitName != null ? unitName : "");//如果持久化单元名称为空,则将容器默认持久化单元名称作用持久化单元名称if ("".equals(unitNameForLookup)) {unitNameForLookup = this.defaultPersistenceUnitName;}//如果持久化单元名称不为空,查找给定持久化单元名称的实体管理器工厂if (!"".equals(unitNameForLookup)) {return findNamedEntityManagerFactory(unitNameForLookup, requestingBeanName);}//如果持久化单元名称为空,获取容器中默认的实体管理器工厂else {return findDefaultEntityManagerFactory(requestingBeanName);}}//查找给定持久化单元名称的实体管理器工厂protected EntityManagerFactory findNamedEntityManagerFactory(String unitName, String requestingBeanName)throws NoSuchBeanDefinitionException {//从Spring所有容器中查找给定名称的实体管理器工厂对象EntityManagerFactory emf = EntityManagerFactoryUtils.findEntityManagerFactory(this.beanFactory, unitName);//将持久化单元名称和查找到的实体管理器工厂对象向Spring容器注册if (this.beanFactory instanceof ConfigurableBeanFactory) {((ConfigurableBeanFactory) this.beanFactory).registerDependentBean(unitName, requestingBeanName);}return emf;}//获取容器默认的实体管理器工厂protected EntityManagerFactory findDefaultEntityManagerFactory(String requestingBeanName)throws NoSuchBeanDefinitionException{//从Spring所有容器中查找给定类型的Bean的名称String[] beanNames =BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, EntityManagerFactory.class);//如果从Spring容器中刚好查找到一个Bean名称if (beanNames.length == 1) {//持久化单元名称就是查找到的Bean名称String unitName = beanNames[0];//从Spring容器中查找给定持久化单元名称的实体管理器工厂BeanEntityManagerFactory emf = (EntityManagerFactory) this.beanFactory.getBean(unitName);//将查找到的实体管理器工厂Bean和持久化单元名称向Spring容器注册if (this.beanFactory instanceof ConfigurableBeanFactory) {((ConfigurableBeanFactory) this.beanFactory).registerDependentBean(unitName, requestingBeanName);}return emf;}else {throw new NoSuchBeanDefinitionException(EntityManagerFactory.class, "expected single bean but found " + beanNames.length);}}?
?
//解析持久化注解public PersistenceElement(Member member, PropertyDescriptor pd) {super(member, pd);//获取当前元素对象AnnotatedElement ae = (AnnotatedElement) member;//获取当前元素对象的@PersistenceContext注解PersistenceContext pc = ae.getAnnotation(PersistenceContext.class);//获取当前元素对象的@PersistenceUnit注解PersistenceUnit pu = ae.getAnnotation(PersistenceUnit.class);//资源类型为实体管理器Class resourceType = EntityManager.class;//如果元素配置的持久化上下文不为nullif (pc != null) {//如果元素配置的持久化单元也不为nullif (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.properties = properties;}//如果持久化上下文为nullelse {//持久化资源类型为实体管理器工厂resourceType = EntityManagerFactory.class;this.unitName = pu.unitName();}//检查给定的持久化资源类型是字段还是方法类型checkResourceType(resourceType);}?
?
//获取并注入持久化资源protected Object getResourceToInject(Object target, 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, String requestingBeanName) {//以持久化单元名称作为JNDI名称获取持久化上下文作为实体管理器EntityManager em = getPersistenceContext(this.unitName, true);//如果根据JNDI获取到的持久化上下文为nullif (em == null) {//以持久化单元名称作为JNDI名称获取实体管理器工厂EntityManagerFactory emf = getPersistenceUnit(this.unitName);//没有获取到指定JNDI名称的实体管理器工厂if (emf == null) {//根据持久化单元名称向Spring容器查找指定名称的实体管理器工厂emf = findEntityManagerFactory(this.unitName, requestingBeanName);}//根据实体管理器工厂和持久化属性创建一个容器管理的实体管理器em = ExtendedEntityManagerCreator.createContainerManagedEntityManager(emf, this.properties);}//创建实体管理器代理委派调用的实体管理器if (em instanceof EntityManagerProxy &&beanFactory != null && !beanFactory.isPrototype(requestingBeanName)) {extendedEntityManagersToClose.put(target, ((EntityManagerProxy) em).getTargetEntityManager());}return em;}}//创建实体管理器private EntityManager resolveEntityManager(String requestingBeanName) {//以持久化单元名称作为JNDI名称获取持久化上下文作为实体管理器EntityManager em = getPersistenceContext(this.unitName, false);//如果根据JNDI获取到的持久化上下文为nullif (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);}else {//根据持久化注解配置的持久化资源类型创建实体管理器em = SharedEntityManagerCreator.createSharedEntityManager(emf, this.properties, getResourceType());}}return em;} //创建实体管理器工厂private EntityManagerFactory resolveEntityManagerFactory(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的反射机制获取注解配置的信息。