事件机制
ApplicationContext 才支持事件机制 实现ApplicationListener接口作为监听器
事件机制的步骤
- 开发实现ApplicationListener接口的事件监听器类
public class FkListener implements ApplicationListener<ApplicationEvent> {
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("监听"+event);
}
}
- 在容器里配置监听器 该监听器课监听到容器中任何事件(包括容器自己产生事件,程序主动发布的事件)
Spring容器本身引发的事件,
ServletRequestHandledEvent: 在Spring HVC容器中才会出现。当要处理一个请求时才激发 该事件。ContextStartedEvent, Spring容器开始时会激发该事件。ContextStoppedEventSpring容器停止时会激发该事件。ContextClosedEvent: Spring容器 关闭时会激发该事件。ContextRefreshedEvent, Spring容器初始化完成或刷新时会激发该事件。
自定义事件
程序也可以向容器发送事件,只调用ApplicationContext的publcEvent()方法可以发送事件
该事件也会被监听器监听到
可以让容器中A组件 (A Bean) 发送一一个自定义事件,这样监听器Bean (B组件)就会激发。
这种方式就相当于实现“松耦合”的调用,A组件无需获取B组件,但A组件依然可以调用B组件的方法。
Bean的别名
Id属性属于xml的ID类型(它有一些特殊的要求,必须是有效的字符,不能使用特色的字符) 当spring框架和第三方框架整合时,往往需要Bean具有一些特殊字符,此时需要别名 指定别名 1.alias元素,专门已有的Bean创建别名
<bean id="dog" class="com.example.ssm.day3.Dog" name="^_^">
<constructor-arg value="2"/>
<!--去掉set方法的set前缀,name是属性名字-->
<property name="name" value="旺财"/>
</bean>
<!--专门取别名-->
<alias name="dog" alias="*dog*"/>
2.通过name属性,多个别名之间用逗号划分
怎么让Bean获取Spring容器?
让实现BeanB actoryAmare/pplicati onContextAware接口的Bean实例被容器创建以后,会自动回调该接口中定义的如下方法: setBeanF actory(BeanF actory bf) /setApplicati onrContext (ApplicationContext ctx): 该方法有一个参数bf/ctx,该参数指向创建它的Spring容器。
Spring容器调用该方法时,会将自己作为参数传入
public class TestBean implements ApplicationContextAware {
private ApplicationContext ctx;
//该需要向spring容器发送事件。此时需要TestBean就需要获取spring容器
//接口注入
// Spr ing容器会自动检测容器中所有的Bean,如果发现某个Bean买现ApplicationContextAware接口
// Spring容器就会自动调用该Bean的setApplicationContext方法,
//调用该方法时,会将自己容器本身作为参数传入
@Override
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
this.ctx = ctx;
}
public void send(String address, String content) {
ctx.publishEvent(new EmailEvent(this, address, content));
}
}
它几乎于property元素驱动setter方法同时调用
事件和监听器,都不知道彼此的存在,但当事件需要发生时,会被监听器拦截,然后监听器会运行事件的功能,把邮件发送出去。
这次没有在主程序test直接发送文件,而是在容器中调用TestBean , 获取它容器本身,然后调用容器本身的publishEvent向容器发送事件,当向容器发送事件时,会激发监听器。但Testbean 和监听器之间没有任何关系(解耦),但需要先要testBean获取spring容器,使用的就是接口注入。