Spring 的 ApplicationEvent and ApplicationListener

Spring事件监听与通知机制详解
本文深入解析了Spring框架中的ApplicationContext容器、ApplicationEvent事件、ApplicationListener监听器之间的交互过程,通过实例展示了如何注册和触发事件,实现组件间的异步通信。

什么是ApplicationContext? 
它是Spring的核心,Context我们通常解释为上下文环境,但是理解成容器会更好些。 
ApplicationContext则是应用的容器。

Spring把Bean(object)放在容器中,需要用就通过get方法取出来。

ApplicationEvent

是个抽象类,里面只有一个构造函数和一个长整型的timestamp。

ApplicationListener

是一个接口,里面只有一个onApplicationEvent方法。

所以自己的类在实现该接口的时候,要实装该方法。

如果在上下文中部署一个实现了ApplicationListener接口的bean,

那么每当在一个ApplicationEvent发布到 ApplicationContext时,
这个bean得到通知。其实这就是标准的Observer设计模式。

首先创建一个Event事件类:

 

[java]  view plain copy
 
  1.  1public class EmailListEvent extends ApplicationEvent {    
  2.  2.     
  3.  3.     private static final long serialVersionUID = 1L;    
  4.  4.     public String address;    
  5.  5.     public String text;    
  6.  6.     
  7.  7.     public EmailListEvent(Object source) {    
  8.  8.         super(source);    
  9.  9.     }    
  10. 10.     
  11. 11.     public EmailListEvent(Object source, String address, String text) {    
  12. 12.         super(source);    
  13. 13.         this.address = address;    
  14. 14.         this.text = text;    
  15. 15.     }    
  16. 16.     
  17. 17.     public void print() {    
  18. 18.         System.out.println("Hello,Spring Event!!!");    
  19. 19.     }    
  20. 20. }    



 

其次创建一个ApplicationListener类:

 

[java]  view plain copy
 
  1.  1public class EmailNotifier implements ApplicationListener {    
  2.  2.     
  3.  3.     public void onApplicationEvent(ApplicationEvent evt) {    
  4.  4.         if (evt instanceof EmailListEvent) {    
  5.  5.             EmailListEvent emailEvent = (EmailListEvent) evt;    
  6.  6.             emailEvent.print();    
  7.  7.             System.out.println("the source is:" + emailEvent.getSource());    
  8.  8.             System.out.println("the address is:" + emailEvent.address);    
  9.  9.             System.out.println("the mail's context is :" + emailEvent.text);    
  10. 10.         }    
  11. 11.     
  12. 12.     }    
  13. 13. }    



 

接着将Listener注册到Spring的xml文件中:

 

[html]  view plain copy
 
  1. <?xml version="1.0" encoding="UTF-8"?>    
  2.  <beans xmlns="http://www.springframework.org/schema/beans"    
  3.           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
  4.           xmlns:aop="http://www.springframework.org/schema/aop"    
  5.           xmlns:tx="http://www.springframework.org/schema/tx"    
  6.           xsi:schemaLocation="http://www.springframework.org/schema/beans   
  7.           http://www.springframework.org/schema/beans/spring-beans-2.0.xsd    
  8.           http://www.springframework.org/schema/aop   
  9.           http://www.springframework.org/schema/aop/spring-aop-2.0.xsd    
  10.           http://www.springframework.org/schema/tx   
  11.           http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">    
  12.     
  13.      <bean id="emailListListener" class="spring.event.EmailNotifier"></bean>    
  14.         
  15. </beans>    



 

最后创建Demo类:

 

[java]  view plain copy
 
  1.  1public class ListenerEventDemo {    
  2.  2.     
  3.  3.     /**  
  4.  4.      * @param args  
  5.  5.      */    
  6.  6.     public static void main(String[] args) {    
  7.  7.         ApplicationContext context = new ClassPathXmlApplicationContext(    
  8.  8.                 "SpringEvent.xml");    
  9.  9.         EmailListEvent emailListEvent = new EmailListEvent("hello",    
  10. 10.                 "helloSpring@sina.com""this is a test eamil content");    
  11. 11.         //在ApplicationContext中发布一个 ApplicationEvent    
  12. 12.         context.publishEvent(emailListEvent);    
  13. 13.     }    
  14. 14.     
  15. 15. }    



 

测试结果:

[plain]  view plain copy
 
  1. # Hello,Spring Event!!!    
  2. # the source is:hello    
  3. # the address is:helloSpring@sina.com    
  4. # the mail's context is :this is a test eamil content    
# Spring中的Listener概念及其他核心组件 ## 一、Spring Listener(监听器)详解 ### 1. 监听器基本概念 Spring中的Listener是基于观察者模式的事件驱动机制,用于在应用状态变化时执行特定操作。它允许组件在特定事件发生时得到通知,而无需与事件源紧密耦合。 ### 2. 主要监听器类型 #### (1) Servlet监听器 ```java // 示例:HttpSessionListener public class MySessionListener implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent se) { System.out.println("Session created: " + se.getSession().getId()); } @Override public void sessionDestroyed(HttpSessionEvent se) { System.out.println("Session destroyed"); } } ``` #### (2) Spring应用上下文监听器 ```java // 示例:ApplicationListener @Component public class MyAppListener implements ApplicationListener<ContextRefreshedEvent> { @Override public void onApplicationEvent(ContextRefreshedEvent event) { System.out.println("Application context refreshed!"); } } ``` #### (3) 自定义事件监听器 ```java // 1. 定义自定义事件 public class MyCustomEvent extends ApplicationEvent { public MyCustomEvent(Object source) { super(source); } } // 2. 发布事件 applicationContext.publishEvent(new MyCustomEvent(this)); // 3. 监听自定义事件 @Component public class CustomEventListener implements ApplicationListener<MyCustomEvent> { @Override public void onApplicationEvent(MyCustomEvent event) { System.out.println("Received custom event"); } } ``` ### 3. 监听器的注册方式 - XML配置:`<listener>`标签 - 注解驱动:`@EventListener`注解 - 编程式注册:`ConfigurableApplicationContext.addApplicationListener()` ## 二、Spring核心组件一览 ### 1. Bean组件 ```java @Component public class MyBean { @PostConstruct public void init() { System.out.println("Bean initialized"); } @PreDestroy public void cleanup() { System.out.println("Bean destroyed"); } } ``` ### 2. AOP (面向切面编程) ```java @Aspect @Component public class LoggingAspect { @Before("execution(* com.example.service.*.*(..))") public void logBefore(JoinPoint joinPoint) { System.out.println("Executing: " + joinPoint.getSignature()); } } ``` ### 3. 事务管理 ```java @Service public class UserService { @Transactional public void updateUser(User user) { // 数据库操作 } } ``` ### 4. MVC组件 ```java @Controller @RequestMapping("/users") public class UserController { @Autowired private UserService userService; @GetMapping("/{id}") public String getUser(@PathVariable Long id, Model model) { model.addAttribute("user", userService.findById(id)); return "userView"; } } ``` ### 5. 数据访问组件 ```java @Repository public class UserRepositoryImpl implements UserRepository { @Autowired private JdbcTemplate jdbcTemplate; public User findById(Long id) { return jdbcTemplate.queryForObject( "SELECT * FROM users WHERE id = ?", new UserRowMapper(), id ); } } ``` ### 6. 配置组件 ```java @Configuration @PropertySource("classpath:app.properties") public class AppConfig { @Bean public DataSource dataSource() { // 数据源配置 } @Bean public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } } ``` ### 7. 消息组件 ```java @Service public class MessageService { @Autowired private JmsTemplate jmsTemplate; public void sendMessage(String message) { jmsTemplate.convertAndSend("mailbox", message); } } ``` ### 8. 安全组件 ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated() .and() .formLogin(); } } ``` ## 三、组件协同工作示例 ```java // 控制器层 @Controller public class OrderController { @Autowired private OrderService orderService; @PostMapping("/orders") public String createOrder(@Valid Order order, BindingResult result) { if (result.hasErrors()) { return "orderForm"; } orderService.processOrder(order); return "redirect:/orders"; } } // 服务层 @Service @Transactional public class OrderServiceImpl implements OrderService { @Autowired private OrderRepository orderRepository; @Autowired private ApplicationEventPublisher eventPublisher; public void processOrder(Order order) { orderRepository.save(order); eventPublisher.publishEvent(new OrderCreatedEvent(this, order)); } } // 事件监听 @Component public class OrderEventListener { @EventListener public void handleOrderCreated(OrderCreatedEvent event) { System.out.println("Processing order: " + event.getOrder()); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值