7.4.5 让Bean获取Spring容器
前面介绍的几个示例,都是程序先创建Spring容器,再调用Spring容器的getBean()方法来获取Spring容器中的Bean。在这种访问模式下,程序中总是持有Spring容器的引用。
在某些特殊的情况下,Bean需要实现某个功能(比如该Bean需要输出国际化消息,或者该Bean需要向Spring容器发布事件…),但该功能必须借助于Spring容器才能实现,此时就必须让该Bean获取它所在的Spring容器,然后借助于Spring容器来实现该功能。
如何获取Bean所在的Spring容器
为了让Bean获取它所在的Spring容器,可以让该Bean实现BeanFactoryAware接口。BeanFactoryAware接口里只有一个方法。
| 方法 | 描述 | ||
|---|---|---|---|
setBeanFactory(BeanFactory beanFactory) |
该方法有一个参数beanFactory,该参数指向创建它的BeanFactory |
||
大部分初学者看到这个setter方法会感到比较奇怪,因为以前定义一个setter方法之后,该setter方法通常都是由程序员来调用的, setter方法参数由程序员指定;即使使用Spring进行依赖注入时, setter方法参数值也是由程序员通过配置文件来指定的。但此处的这个setter方法比较奇怪,这个方法将由Spring调用, Spring调用该方法时会将Spring容器作为参数传入该方法。与该接口类似的还有BeanNameAware、 ResourceLoaderAware接口,这些接口里都会提供类似的setter方法,这些方法也由Spring负责调用。 |
|||
与BeanFactoryAware接口类似的有ApplicationContextAware接口,实现该接口的Bean需要实现setApplicationContext(ApplicationContext applicationContex)方法—该方法也不是由程序员负责调用的而是由Spring来调用的。当Spring容器调用该方法时,它会把自身作为参数传入该方法。 |
|||
| # 程序示例 # | |||
下面示例假设Person类的sayHi()方法必须能输出国际化消息,由于国际化功能需要借助于Spring容器来实现,因此程序就需要让Person类实现Application ContextAware接口。下面是Person类的源代码。 |
|||
| ## 项目结构 ## | |||
| ## Person.java ## | |||
|
上面的Person类实现了ApplicationContextAware接口,并实现了该接口提供的setApplicationContextAware()方法.Spring容器会检测容器中所有的Bean,如果发现某个Bean实现了ApplicationContextAware接口,Spring容器会在创建该Bean之后,自动调用该Bean的setApplicationContextAware()方法,调用该方法时,会将容器本身作为参数传给该方法——该方法的实现部分将Spring传入的参数(容器本身)赋给该Person对象的ctx实例变量,因此接下来即可通过该ctx实例变量来访问容器本身。
将该Bean部署在Spring容器中,部署该Bean与部署其他Bean没有任何区别。
beans.xml
XML配置文件如下:
1 |
|
主程序部分进行简单测试,程序先通过实例化的方法来获得ApplicationContext,然后再通过personBean来获得BeanFactory,并将二者进行比较。主程序如下。
SpringTest.java
1 | package lee; |
Bean获取它所在容器的好处
上面程序执行Person对象的sayHi()方法时,该sayHi()方法就自动具有了国际化的功能,而这种国际化的功能实际上是由Spring容器提供的,这就是让Bean获取它所在容器的好处。
原文链接: 7.4.5 让Bean获取Spring容器