SpringBean实例化之CommonAnnotationBeanPostProcessor解析

前言

CommonAnnotationBeanPostProcessor这个BeanPostProcessor通过继承InitDestroyAnnotationBeanPostProcessor对@javax.annotation.PostConstruct和@javax.annotation.PreDestroy注解的支持。以及依据bean name依赖注入的@javax.annotation.Resource支持。也支持WebServiceRef注解,具有创建JAX-WS服务端点的能力。最后,处理器还支持EJB3(@EJB)。
在这里插入图片描述

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

	@Nullable
	private static Class<? extends Annotation> webServiceRefClass;

	@Nullable
	private static Class<? extends Annotation> ejbRefClass;
	
    private final Set<String> ignoredResourceTypes = new HashSet<>(1);

	private boolean fallbackToDefaultTypeMatch = true;

	private boolean alwaysUseJndiLookup = false;

	private transient BeanFactory jndiFactory = new SimpleJndiBeanFactory();

	@Nullable
	private transient BeanFactory resourceFactory;

	@Nullable
	private transient BeanFactory beanFactory;

	@Nullable
	private transient StringValueResolver embeddedValueResolver;

	private final transient Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);

	static {
		try {
			@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 {
			@SuppressWarnings("unchecked")
			Class<? extends Annotation> clazz = (Class<? extends Annotation>)
					ClassUtils.forName("javax.ejb.EJB", CommonAnnotationBeanPostProcessor.class.getClassLoader());
			ejbRefClass = clazz;
		}
		catch (ClassNotFoundException ex) {
			ejbRefClass = null;
		}
	}

	public CommonAnnotationBeanPostProcessor() {
		setOrder(Ordered.LOWEST_PRECEDENCE - 3);
		setInitAnnotationType(PostConstruct.class);
		setDestroyAnnotationType(PreDestroy.class);
		ignoreResourceType("javax.xml.ws.WebServiceContext");
	}
}

一、注解信息读取和包装

CommonAnnotationBeanPostProcessor继承了InitDestroyAnnotationBeanPostProcessor,这两个注解是由这个父类完成解析的,在CommonAnnotationBeanPostProcessor构造函数中调用父类的方法setInitAnnotationType()和setDestroyAnnotationType()将这两个注解Class对象传递给父类。
InitDestroyAnnotationBeanPostProcessor中分三个阶段完成这两个注解功能,分别为:

CommonAnnotationBeanPostProcessor是一个InstantiationAwareBeanPostProcessor,但其postProcessBeforeInstantiation返回为null,所以他不行影响spring内部正常的bean实例化流程。在调用bean的构造器后,又因为其是一个MergedBeanDefinitionPostProcessor,所以他会执行其postProcessMergedBeanDefinition方法。CommonAnnotationBeanPostProcessor是在postProcessMergedBeanDefinition方法中完成了其对@PostConstruct@PreDestroy,@Resource注解的处理

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


	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName){
	    //对@@PostConstruct和@PreDestroy`注解的处理
		super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
		//对@Resource注解的处理 
		InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}
}
1.1 对@PostConstruct和@PreDestroy注解信息的读取
public class InitDestroyAnnotationBeanPostProcessor implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, Serializable {

	//CommonAnnotationBeanPostProcessor在初始化时向里面放置了@PostConstruct注解
	private Class<? extends Annotation> initAnnotationType;
	//CommonAnnotationBeanPostProcessor在初始化时向里面放置了@PreDestroy注解
	private Class<? extends Annotation> destroyAnnotationType;
	@Nullable
	private final transient Map<Class<?>, LifecycleMetadata> lifecycleMetadataCache = new ConcurrentHashMap<>(256);

	@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,Class<?> beanType,String beanName){
		LifecycleMetadata metadata = findLifecycleMetadata(beanType);
		metadata.checkConfigMembers(beanDefinition);
	}
	
	private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
		if (this.lifecycleMetadataCache == null) {
			// 在反序列化之后,在销毁期间。。。
			return buildLifecycleMetadata(clazz);
		}
		// 首先对并发映射进行快速检查,只需最少的锁定。
		LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz);
		if (metadata == null) {
			synchronized (this.lifecycleMetadataCache) {
				metadata = this.lifecycleMetadataCache.get(clazz);
				if (metadata == null) {
					metadata = buildLifecycleMetadata(clazz);
					this.lifecycleMetadataCache.put(clazz, metadata);
				}
				return metadata;
			}
		}
		return metadata;
	}

	private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
		List<LifecycleElement> initMethods = new ArrayList<>();
		List<LifecycleElement> destroyMethods = new ArrayList<>();
		Class<?> targetClass = clazz;

		do {
			final List<LifecycleElement> currInitMethods = new ArrayList<>();
			final List<LifecycleElement> currDestroyMethods = new ArrayList<>();

			ReflectionUtils.doWithLocalMethods(targetClass, method -> {
			    //查看方法上是否有@PostConstruct注解存在
				if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
				    //如果有把他封装成LifecycleElement对象,储存起来
					LifecycleElement element = new LifecycleElement(method);
					currInitMethods.add(element);
				}
				 //查看方法上是否有@PreDestroy注解存在
				if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
				   //如果有把他封装成LifecycleElement对象,储存起来
					currDestroyMethods.add(new LifecycleElement(method));
				}
			});
             // 初始化方法父类早于子类
			initMethods.addAll(0, currInitMethods);
			// 销毁方法父类晚于子类
			destroyMethods.addAll(currDestroyMethods);
			targetClass = targetClass.getSuperclass();
		}
		while (targetClass != null && targetClass != Object.class);
        //把他们封装成LifecycleMetadata对象
		return new LifecycleMetadata(clazz, initMethods, destroyMethods);
	}

把@PostConstruct和@PreDestroy注解信息和其方法信息包装成LifecycleMetadata存储到lifecycleMetadataCache中

private class LifecycleMetadata {

		private final Class<?> targetClass;

		private final Collection<LifecycleElement> initMethods;

		private final Collection<LifecycleElement> destroyMethods;
1.2 对@Resource注解的处理
public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
		implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {

     
	private final transient Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);

	@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
	    //这个时处理@PostConstruct`和`@PreDestroy的
		super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
		//这里是处理@Resource的
		InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}
	
	private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz,  PropertyValues pvs) {
		//退回到类名作为缓存键,以便与自定义调用者向后兼容。
		String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
		//先根据键值从缓存injectionMetadataCache中查询对应的InjectionMetadata
		InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
		//如果metadata为null
		if (InjectionMetadata.needsRefresh(metadata, clazz)) {
			synchronized (this.injectionMetadataCache) {
				metadata = this.injectionMetadataCache.get(cacheKey);
				if (InjectionMetadata.needsRefresh(metadata, clazz)) {
					if (metadata != null) {
						metadata.clear(pvs);
					}
					//开始处理@Resource
					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 -> {
				if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
					if (Modifier.isStatic(field.getModifiers())) {
						throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields");
					}
					currElements.add(new WebServiceRefElement(field, field, null));
				}
				else if (ejbRefClass != null && field.isAnnotationPresent(ejbRefClass)) {
					if (Modifier.isStatic(field.getModifiers())) {
						throw new IllegalStateException("@EJB annotation is not supported on static fields");
					}
					currElements.add(new EjbRefElement(field, field, null));
				}
				else if (field.isAnnotationPresent(Resource.class)) {
					if (Modifier.isStatic(field.getModifiers())) {
						throw new IllegalStateException("@Resource annotation is not supported on static fields");
					}
					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))) {
					if (webServiceRefClass != null && bridgedMethod.isAnnotationPresent(webServiceRefClass)) {
						if (Modifier.isStatic(method.getModifiers())) {
							throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods");
						}
						if (method.getParameterCount() != 1) {
							throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
						}
						PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
						currElements.add(new WebServiceRefElement(method, bridgedMethod, pd));
					}
					else if (ejbRefClass != null && bridgedMethod.isAnnotationPresent(ejbRefClass)) {
						if (Modifier.isStatic(method.getModifiers())) {
							throw new IllegalStateException("@EJB annotation is not supported on static methods");
						}
						if (method.getParameterCount() != 1) {
							throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method);
						}
						PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
						currElements.add(new EjbRefElement(method, bridgedMethod, pd));
					}
					else if (bridgedMethod.isAnnotationPresent(Resource.class)) {
						if (Modifier.isStatic(method.getModifiers())) {
							throw new IllegalStateException("@Resource annotation is not supported on static methods");
						}
						Class<?>[] paramTypes = method.getParameterTypes();
						if (paramTypes.length != 1) {
							throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
						}
						if (!this.ignoredResourceTypes.contains(paramTypes[0].getName())) {
							PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
							currElements.add(new ResourceElement(method, bridgedMethod, pd));
						}
					}
				}
			});

			elements.addAll(0, currElements);
			targetClass = targetClass.getSuperclass();
		}
		while (targetClass != null && targetClass != Object.class);

		return new InjectionMetadata(clazz, elements);
	}

@Resource如果遇到static属性或者方法,他是直接报错,@Autowired如果遇到static属性或者方法,他是不会处理
CommonAnnotationBeanPostProcessor把@Resource属性或者方法都包装成ResourceElement,而AutowiredAnnotationBeanPostProcessor把@Autowired属性包装成AutowiredFieldElement,@Autowired方法包装成AutowiredMethodElement

二、@Resource属性赋值

地点发生在populateBean()方法,因为其方法postProcessAfterInstantiation()返回的是true,所以他会调用其postProcessProperties方法为bean赋值属性,其对@Resource属性赋值或者方法的执行都发生在这

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

	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
		InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
		try {
			metadata.inject(bean, beanName, pvs);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
		}
		return pvs;
	}

	public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
			Collection<InjectedElement> checkedElements = this.checkedElements;
			Collection<InjectedElement> elementsToIterate =
					(checkedElements != null ? checkedElements : this.injectedElements);
			if (!elementsToIterate.isEmpty()) {
				for (InjectedElement element : elementsToIterate) {
					if (logger.isTraceEnabled()) {
						logger.trace("Processing injected element of bean '" + beanName + "': " + element);
					}
					element.inject(target, beanName, pvs);
				}
			}
		}
}

底层执行的是ResourceElement的inject方法,但ResourceElement没有重写其父类InjectedElement的inject方法,所以执行的方法还是其父类的

public class InjectionMetadata {

	public abstract static class InjectedElement {
	
		protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
						throws Throwable {
		
					if (this.isField) {
						Field field = (Field) this.member;
						ReflectionUtils.makeAccessible(field);
						field.set(target, getResourceToInject(target, requestingBeanName));
					}
					else {
						if (checkPropertySkipping(pvs)) {
							return;
						}
						try {
							Method method = (Method) this.member;
							ReflectionUtils.makeAccessible(method);
							method.invoke(target, getResourceToInject(target, requestingBeanName));
						}
						catch (InvocationTargetException ex) {
							throw ex.getTargetException();
						}
					}
				}
		}
}

三、@PostConstruct和@PreDestroy标注方法的执行

在initializeBean()方法中,因为其是一个先执行其BeanPostProcessor,所以他会先执行其postProcessBeforeInitialization,在调用其初始化方法,在调用其postProcessAfterInitialization,这里先说明下,其postProcessAfterInitialization方法没有做任何处理,@PostConstruct和@PreDestroy标注方法的执行发生在postProcessBeforeInitialization方法中,

public class InitDestroyAnnotationBeanPostProcessor implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, Serializable {

	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
		try {
			metadata.invokeInitMethods(bean, beanName);
		}
		catch (InvocationTargetException ex) {
			throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
		}
		return bean;
	}

	public void invokeInitMethods(Object target, String beanName) throws Throwable {
				Collection<LifecycleElement> checkedInitMethods = this.checkedInitMethods;
				Collection<LifecycleElement> initMethodsToIterate =
						(checkedInitMethods != null ? checkedInitMethods : this.initMethods);
				if (!initMethodsToIterate.isEmpty()) {
					for (LifecycleElement element : initMethodsToIterate) {
						if (logger.isTraceEnabled()) {
							logger.trace("Invoking init method on bean '" + beanName + "': " + element.getMethod());
						}
						//其底层代码如下
						//ReflectionUtils.makeAccessible(this.method);
			            //this.method.invoke(target, (Object[]) null);
						element.invoke(target);
					}
				}
	}
}

其是在这边我们可以看出,@PostConstruct和@PreDestroy标注的方法执行顺序,先于通过实现 InitializingBean/DisposableBean 接口来定制的初始化之后/销毁方法。

@Component
public class Child implements InitializingBean {

	@PostConstruct
	public void init(){
		System.out.println("通过@PostConstruct指定的初始化方法");
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("通过实现InitializingBean接口指定的初始化方法");
	}
}

通过@PostConstruct指定的初始化方法
通过实现InitializingBean接口指定的初始化方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值