Bean對IOC容器的感知

本節主要學習Bean對IOC容器的感知

容器管理的Bean一般不需要了解容器的狀態和直接使用容器,但在某些情況下,需要在Bean中直接對IOC容器進行操作,這時候就需要在Bean中設定對容器的感知。Spring IOC容器也提供了該功能,它是通過特定的aware接口完成的。aware接口有以下這些:

  • BeanNameAware ,可以在Bean中得到它在IOC容器中的Bean實例名稱
  • BeanFactoryAware,可以在Bean中得到Bean所在的IOC容器,從而直接在Bean中使用IOC容器的服務。
  • ApplicationContextAware,可以在Bean中得到Bean所在的應用上下文,從而直接在Bean中使用應用上下文的服務。
  • MessageSourceAware,在Bean中可以得到消息源
  • ApplicationEventpublisherAware,在Bean中得到應用上下文的事件發佈器,從而可以在Bean中發佈應用上下文的事件。
  • ResourceLoaderAware,在Bean中得到ResourceLoader,從而在Bean中得到ResourceLoader加載外部對應的Resource資源。

比如ApplicationContextAware

public interface ApplicationContextAware extends Aware {

	void setApplicationContext(ApplicationContext applicationContext) throws BeansException;

}

這個setApplicationContext方法的回調是由容器自動完成的.

ApplicationContextAwareProcessor作爲BeanPostProcessor的實現,對一系列的aware進行了調用。

class ApplicationContextAwareProcessor implements BeanPostProcessor {

	private final ConfigurableApplicationContext applicationContext;

	private final StringValueResolver embeddedValueResolver;


	/**
	 * Create a new ApplicationContextAwareProcessor for the given context.
	 */
	public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
		this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
	}


	@Override
	@Nullable
	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<Object>) () -> {
				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) {
				((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
			}
		}
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) {
		return bean;
	}

}

postProcessBeforeInitialization會在初始化Bean的實現過程中被調用,從而實現對aware接口的相關注入。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章