Bean对IOC容器的感知

Bean对IOC容器的感知

容器管理的Bean一般不需要了解容器的状态和直接使用容器,但在某些情况下,是需要在Bean、中直接对IOC容器进行操作的,这时候,就需要再Bean中设定对容器的感知。——?IOC容器提供了该功能——通过aware接口来完成的。
aware接口有以下这些:

  • BeanNameAware,可以在Bean中得到它在IOC容器中的Bean实例名称。
  • BeanFactoryAware,可以在Bean中得到Bean所在的IOC容器,从而直接在Bean中使用IOC容器的服务。
  • ApplicationContextAware,在Bean中得到Bean所在的应用上下文,从而直接在Bean中使用应用上下文的服务。
  • MessageSourceAware,在Bean中可以得到消息源。
  • ApplicationEvenetPublisherAware,在Bean中可以得到ResourceLoader,从而在Bean中使用ResourceLoader加载外部对应的Resource资源。
    在设置Bean的属性之后,调用初始化回调方法之前,Spring会调用aware接口中的setter方法。以ApplicationContextAware为例,分析对应的设计和实现。这个接口定义得很简单。
public interface ApplicationContextAware extends Aware {
	/**
	 * Set the ApplicationContext that this object runs in.
	 * Normally this call will be used to initialize the object.
	 * <p>Invoked after population of normal bean properties but before an init callback such
	 * as {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}
	 * or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader},
	 * {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
	 * {@link MessageSourceAware}, if applicable.
	 * @param applicationContext the ApplicationContext object to be used by this object
	 * @throws ApplicationContextException in case of context initialization errors
	 * @throws BeansException if thrown by application context methods
	 * @see org.springframework.beans.factory.BeanInitializationException
	 */
	void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

它是一个回调函数,在Bean中通过实现这个函数,可以在容器回调该aware接口方法时使注入的applicationContext引用在Bean中保存下来,供Bean需要使用ApplicationContext的基本服务时使用。这个对setApplicationContext方法的回调是由容器自动完成的。可以看到,一个ApplicationContextAwareProcessor作为BeanPostProcessor的实现,对一系列的aware回调进行了调用,比如对ResourceLoaderAware接口的盗用,对ApplicationEventPublisherAware接口的调用,以及对MessageSourceAware和ApplicationContextAware的接口调用等。

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
	if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
			bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
			bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
		return bean;
	}
	AccessControlContext acc = null;
	if (System.getSecurityManager() != null) {
		acc = this.applicationContext.getBeanFactory().getAccessControlContext();
	}

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

作为依赖注入的一部分,postProcessBeforeInitialzation会在initilizeBean的实现过程中被调用,从而实现对aware接口的相关注入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值