在某些情况下,容器中的Bean可能需要主动访问spring容器本身,Spring也为这种需求做好了准备。
实现BeanFactoryAware接口的Bean,拥有访问BeanFactory容器的能力,实现BeanFactoryAware接口的Bean实例被容器创建以后,它会拥有一个指向创建它的BeanFactory的引用,BeanFactoryAware只有如下一个方法:
setBeanFactory(BeanFactory beanFactory) :该方法有一个参数,该参数指向创建它的BeanFactory。注:改方法是系统主动调用,不需我们显示调用。
大部分初学者看到这个setter方法会感到比较奇怪,因为以前我们定义个setter方法时,该方法通常是由程序员来调用,setter参数是由程序员来指定的;即使使用spring依赖注入时,setter方法的参数是通过配置文件来指定的,但此处的这个setter方法比较奇怪,这个方法将由spring主动调用,spring调用该方法时将spring容器作为参数传入到该方法。与该接口类似的还有,BeanNameAware、ResourceLoaderAware接口,这些接口都会提供类似的setter方法,这些方法也由spring负责调用。
与BeanFactoryAware接口类似的还有:ApplicationContextAware接口,实现该接口的Bean需要实现这个方法:
setApplicationContext(ApplicationContext applicationContext)该方法同样是有spring自动调用的。当spring容器调用该方法时,会把自身作为参数传入该方法。
public class myApplicationContext implements ApplicationContextAware{
private ApplicationContext applicationContext;
public ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
System.out.println("我被系统自动调用了!!");
this.applicationContext = applicationContext;
}
}
myApplicationContext 实现了ApplicationContextAware接口,并实现了该接口提供的方法,这就使得该Bean实例可以直接访问到创建它的spring容器。
将该Bean配置到xml文件中:
<bean id="myapplicationcontext" class="com.xxx.xxx.test.myApplicationContext"/>
进行简单的测试:
public class TestClass {
@Test
public void testHelloimple2() throws IOException {
ApplicationContext act= new ClassPathXmlApplicationContext(url);
System.out.println("=======================================");
myApplicationContext mact=act.getBean("myapplicationcontext",myApplicationContext.class);
System.out.println(mact.getApplicationContext());
System.out.println(act);
System.out.println(act==mact.getApplicationContext());
}
}
输出:
我被系统自动调用了!!
=======================================
org.springframework.context.support.ClassPathXmlApplicationContext@5ecddf8f: startup date [Tue Mar 17 16:56:46 CST 2015]; root of context hierarchy
org.springframework.context.support.ClassPathXmlApplicationContext@5ecddf8f: startup date [Tue Mar 17 16:56:46 CST 2015]; root of context hierarchy
true
实现ApplicationContextAware接口让Bean拥有了访问容器的能力,但是污染了代码,导致代码与spring接口耦合在一起。因此,如果不是特别必要,建议不要直接访问容器。