Spring自定义事件处理:setApplicationEventPublisher注入对象及决策机制问询
Spring 事件发布与 Aware 接口注入问题解答
先把你提供的完整代码按文件整理如下:
MyEventPublisher.java
package com.ca.spring; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; public class MyEventPublisher implements ApplicationEventPublisherAware{ private ApplicationEventPublisher applicationEventPublisher; @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.applicationEventPublisher = applicationEventPublisher; } public void publish() { System.out.println("MyEventPublisher.publish() invoked ... "); applicationEventPublisher.publishEvent(new MyEvent(this)); } }
MyEvent.java
package com.ca.spring; import org.springframework.context.ApplicationEvent; public class MyEvent extends ApplicationEvent{ private static final long serialVersionUID = 1L; public MyEvent(Object source) { super(source); } }
MyEventListener.java
package com.ca.spring; import org.springframework.context.ApplicationListener; public class MyEventListener implements ApplicationListener<MyEvent>{ @Override public void onApplicationEvent(MyEvent e) { System.out.println("MyEventListener.onApplicationEvent() invoked: " + e.getSource().getClass().getName()); } }
SpringApp.java
package com.ca.spring; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringApp { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("SpringBeans.xml"); ((MyEventPublisher)context.getBean("myEventPublisher")).publish(); context.close(); } }
SpringBeans.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- Springbeans.xml --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="myEventPublisher" class="com.ca.spring.MyEventPublisher"/> <bean id="myEventListener" class="com.ca.spring.MyEventListener"/> </beans>
问题1:未在XML中声明依赖时,setApplicationEventPublisher()会注入哪个对象?
答案:注入的是当前Spring容器的实例,也就是你代码里的ClassPathXmlApplicationContext对象。因为Spring的ApplicationContext接口直接继承了ApplicationEventPublisher接口,容器本身就具备事件发布的能力,所以会把自身作为ApplicationEventPublisher的实现类注入到MyEventPublisher中。
问题2:Spring框架是如何决定注入该特定对象的?
这要归功于Spring的Aware接口机制,具体流程如下:
- 当Spring容器初始化
myEventPublisher这个Bean时,会自动检查它是否实现了ApplicationEventPublisherAware这类Aware系列接口; - Spring内部有专门的
BeanPostProcessor(比如ApplicationContextAwareProcessor)负责处理所有Aware接口的Bean; - 这个处理器识别到
MyEventPublisher实现了ApplicationEventPublisherAware后,会调用对应的setApplicationEventPublisher()方法,把容器自身(因为ApplicationContext是ApplicationEventPublisher的实现类)传递进去; - 整个过程完全是Spring容器的内置逻辑,不需要你手动配置依赖,目的是让Bean能够主动获取容器的核心组件,扩展自身功能。
内容的提问来源于stack exchange,提问作者overexchange
相关产品推荐
相关产品推荐

