spring-第四篇之让bean获取所在的spring容器
1、如上一篇文章所述,有时候bean想发布一些容器事件,就需要先获取spring容器,然后将Event交由spring容器将事件发布出去。
为了让bean获取它所在的spring容器,可以让该bean实现BeanFactoryAware接口,BeanFactoryAware接口只有一个方法。
setBeanFactory(BeanFactory beanFactory):beanFactory参数指向创建它的BeanFactory。这个setter方法与我们往常的setter方法的使用有些差别,它并不是由我们来使用,而是由spring调用,spring调用该方法时会将spring容器作为参数传入该方法。
与BeanFactoryAware接口类似的有ApplicationContextAware接口,实现该接口的bean需要实现setApplicationContext(ApplicationContext applicationContext)方法,该方法也是由spring调用。spring容器调用该方法时,将会把自身作为参数传入该方法。
2、还是对上一篇文章的例子做一些修改来说明
目录结构
增加一个Person.java业务bean,其实现了ApplicationContextAware接口。
package com.lfy.bean; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import com.lfy.event.EmailEvent; public class Person implements ApplicationContextAware { private ApplicationContext ctx; @Override public void setApplicationContext(ApplicationContext arg0) throws BeansException { this.ctx=arg0; } /** * 模拟人发送邮件业务,发送邮件将触发EmailEvent事件 * @param event */ public void sendEmail(EmailEvent event) { System.out.println("\n执行了Person.sendEmail()方法,模拟发出了一封邮件...\n"); this.ctx.publishEvent(event); } }
修改beans.xml,将Person注册到spring容器中
<?xml version="1.0" encoding="UTF-8"?> <!-- spring配置文件的根元素,使用spring-beans-4.0.xsd语义约束 --> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <!-- 注册监听器 --> <bean class="com.lfy.listener.EmailNotifier"/> <bean id="person" class="com.lfy.bean.Person"/> </beans>
修改SpringListenerTest.java,模拟某人发送邮件,触发了邮件发送监听事件。
package com.lfy.main; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.lfy.bean.Person; import com.lfy.event.EmailEvent; public class SpringListenerTest { public static void main(String[] args) { //创建spring容器 ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml"); EmailEvent ele=new EmailEvent("test","spring_test@163.com","this is a test"); //发布容器事件 //ctx.publishEvent(ele); Person p=ctx.getBean("person", Person.class); p.sendEmail(ele); } }
启动运行我们的测试程序:
3、总结
spring容器会检测容器中的所有bean(比如本例中的Person bean),如果发现某个bean实现了ApplicationContextAware接口,spring容器会在创建该bean后,自动调用该bean的setApplicationContext()方法,调用该方法,会将spring容器本身作为参数传递该方法,总而实现让bean获取所在的spring容器。