7.4.5 让Bean获取Spring容器
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
1 | package org.crazyit.app.service; |
上面的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
获取它所在容器的好处。