スプリングシリーズ3-バックプロセッサ

4821 ワード

Springのbeanに対する割当、他のコンポーネントを注入し、ライフサイクル注解機能、@Asyncなどの機能は、下位層でBenPostProcessorつまりバックプロセッサに対する支持によって実現されます.いくつかの一般的なポストプロセッサを参照してください.具体的なspringソースは今後分析されます.
1.Application Contect Aware
クラスはApplication Contect Awareインターフェースを実現して、コンテキストApplication Controtexを取得して、自分の業務操作に使うことができます.
public class A implements ApplicationContextAware{
	private ApplicationContext applicationContext;
	public A(){
	}
	@PostConstruct
	public void init(){
		System.out.println("....@PostConstruct........");
	}
	
	@PreDestroy
	public void destory(){
		System.out.println("....@PreDestroy......");
	}
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		// applicationContext   ,    
		System.out.println(".....applicationContext........");
		this.applicationContext = applicationContext;
	}
}
Application Contect Awareに対応する後置プロセッサは、Appplication Contect Aware Processorです.ソースコードをちょっと見てみます.
//           ,  
	public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
		AccessControlContext acc = null;
		//    
		if (System.getSecurityManager() != null &&
				(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
						bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
						bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
		}

		if (acc != null) {
			AccessController.doPrivileged((PrivilegedAction) () -> {
				//  
				invokeAwareInterfaces(bean);
				return null;
			}, acc);
		}
		else {
			//  
			invokeAwareInterfaces(bean);
		}

		return bean;
	}
private void invokeAwareInterfaces(Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof EnvironmentAware) {
				((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
			}
			if (bean instanceof EmbeddedValueResolverAware) {
				((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
			}
			if (bean instanceof ResourceLoaderAware) {
				((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
			}
			if (bean instanceof ApplicationEventPublisherAware) {
				((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
			}
			if (bean instanceof MessageSourceAware) {
				((MessageSourceAware) bean).setMessageSource(this.applicationContext);
			}

			if (bean instanceof ApplicationContextAware) {
				//      setApplicationContext  
				//applicationContext               
				((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
			}
		}
	}
2.BeanValidation PostProcessor
BeanValidation PostProcessorはデータチェックを行います.たとえば、@Validated類を追加した場合、JSRによって提供されたチェックノート(たとえば@Null)をチェックします.ソースのポイントは以下の通りです.
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (!this.afterInitialization) {
			//         
			doValidate(bean);
		}
		return bean;
	}
	
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (this.afterInitialization) {
			//         
			doValidate(bean);
		}
		return bean;
	}
3.Init Destroy AnnotationBeanPostProcessor
後置プロセッサは@PostConstruct、@Predestroyを処理します.キーソースは以下の通りです.
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		//         ,@PostConstruct     
		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 checkedInitMethods = this.checkedInitMethods;
			Collection 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());
					}
					//    ,target     bean
					element.invoke(target);
				}
			}
		}