Spring神经元(第三根)

87 阅读3分钟

事件机制

ApplicationContext 才支持事件机制 实现ApplicationListener接口作为监听器

事件机制的步骤

  1. 开发实现ApplicationListener接口的事件监听器类
public class FkListener implements ApplicationListener<ApplicationEvent> {  
	
    @Override  
    public void onApplicationEvent(ApplicationEvent event) {  
        System.out.println("监听"+event);  
    }  
}
  1. 在容器里配置监听器 该监听器课监听到容器中任何事件(包括容器自己产生事件,程序主动发布的事件)

Spring容器本身引发的事件,

  • ServletRequestHandledEvent: 在Spring HVC容器中才会出现。当要处理一个请求时才激发 该事件。
  • ContextStartedEvent, Spring容器开始时会激发该事件。
  • ContextStoppedEvent Spring容器停止时会激发该事件。
  • ContextClosedEvent: Spring容器 关闭时会激发该事件。
  • ContextRefreshedEvent, Spring容器初始化完成或刷新时会激发该事件。

自定义事件

程序也可以向容器发送事件,只调用ApplicationContextpublcEvent()方法可以发送事件 该事件也会被监听器监听到 可以让容器中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方法同时调用

image.png

事件和监听器,都不知道彼此的存在,但当事件需要发生时,会被监听器拦截,然后监听器会运行事件的功能,把邮件发送出去。

image.png

这次没有在主程序test直接发送文件,而是在容器中调用TestBean , 获取它容器本身,然后调用容器本身的publishEvent向容器发送事件,当向容器发送事件时,会激发监听器。但Testbean 和监听器之间没有任何关系(解耦),但需要先要testBean获取spring容器,使用的就是接口注入。