spring事件学习和浅析
2017-10-31 00:00
302 查看
摘要: spring的事件模型,说白了就是一个类似发布订阅的功能,在比较复杂的业务场景中,我们可以利用spring event 事件模型来简化程序逻辑,某些场景下还可以提高程序的执行效率。
业务场景:在一个业务系统中,订单提交后并计算该笔订单的手续费。
为了下单这个逻辑的完整性和代码执行更高效,我们可以把“下单”和“计算手续费”拆分成两个不同的业务逻辑。
控制台结果:
业务场景:在一个业务系统中,订单提交后并计算该笔订单的手续费。
为了下单这个逻辑的完整性和代码执行更高效,我们可以把“下单”和“计算手续费”拆分成两个不同的业务逻辑。
一、定义一个发布事件的工具类EventUtils
这个工具类只负责发布事件public class EventUtils implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public static void publishEvent(final ApplicationEvent event) { if (TransactionSynchronizationManager.isActualTransactionActive()) { TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { @Override public void afterCommit() { applicationContext.publishEvent(event); super.afterCommit(); } }); } else { applicationContext.publishEvent(event); } } }
二、定义一个事件模型
就是创建一个普通java类并继承org.springframework.context.ApplicationEvent,它主要负责数据传输public class OrderSubmitEvent extends ApplicationEvent{ private static final long serialVersionUID = -726198855342137539L; public OrderSubmitEvent(Object source) { super(source); } }
三、 定义一个订单服务类
@Service public class OrderService { static final Logger logger = LoggerFactory.getLogger(OrderService.class); // 创建订单方法 ps:这只是测试代码,如果写正式代码建议定义接口 public void create(){ logger.info("OrderService.create"); // 执行创建订单逻辑 // do something... // 要传输的信息,这里可以是object类型,我为了演示就直接传一个字符串过去 String message = "订单提交成功了!"; // 发布事件 EventUtils.publishEvent(new OrderSubmitEvent(message)); logger.info("OrderService.publishEvent"); } }
四、写监听器
既然订单创建好了并发布了事件,那我们就需要监听这个“订单已提交”的事件,去执行自己的逻辑,这个监听器需要实现 org.springframework.context.ApplicationListener 然后重写它的方法。@Component public class OrderSubmitListener implements ApplicationListener<OrderSubmitEvent>{ final static Logger logger = LoggerFactory.getLogger(OrderSubmitListener.class); @Async @Override public void onApplicationEvent(OrderSubmitEvent orderCompleteEvent) { Object source = orderCompleteEvent.getSource(); logger.info("OrderSubmitListener onApplicationEvent source:[{}]", ToStringBuilder.reflectionToString(source)); } }
五、配置文件
直接贴代码,如果直接复制下面配置,需要修改一下你们的包路径<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd"> <!-- 扫描远程服务类注解 !!!记得自己改包名!!!--> <context:component-scan base-package="com.xxx.**.**" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> <context:include-filter type="annotation" expression="org.springframework.stereotype.Service" /> <context:include-filter type="annotation" expression="org.springframework.stereotype.Component" /> </context:component-scan> <!-- 方便在非spring管理环境中获取bean !!!记得自己改包名--> <bean id="eventUtils" class="com.xxx.util.EventUtils"/> <!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
六、测试
@RestController @RequestMapping(value = "api/test",produces = "text/plain;charset=UTF-8") public class TestController { static final Logger logger = LoggerFactory.getLogger(TestController.class); @Autowired private Configuration configuration; @Autowired private OrderService orderService; @RequestMapping(value = "/index") public String order(){ logger.info("TestController create order run"); orderService.create(); return "index"; } }
控制台结果:
17:10:53.936 [qtp1899280551-20] INFO com.xxx.web.controller.TestController - TestController create order run 17:10:53.937 [qtp1899280551-20] INFO com.xxx.springevent.OrderService - OrderService.create 17:10:53.947 [qtp1899280551-20] INFO com.xxx.springevent.OrderSubmitListener - OrderSubmitListener onApplicationEvent source:[java.lang.String@73bd9107[value={订,单,提,交,成,功,了,!},hash=171729329]] 17:10:53.947 [qtp1899280551-20] INFO com.xxx.springevent.OrderService - OrderService.publishEvent
相关文章推荐
- Spring 注解学习手札(四) 持久层浅析
- Spring通过容器获取配置对象及事件注入(学习笔记二)
- Spring源码学习IOC(7):浅析aware相关接口
- Spring深度学习之架构浅析(一)
- Spring 注解学习手札(四) 持久层浅析
- Java天地 学习探讨Java Spring中使用classpath加载配置文件浅析
- Spring入门学习笔记(3)——事件处理类
- Spring学习之事件传播
- 代码干货 | spring中自定义Event事件的使用和浅析
- spring学习教程8-自定义属性编辑器PropertyEditor 和自定义事件
- spring中自定义Event事件的使用和浅析
- spring学习历程 之 事件(二)
- spring5/springboot2源码学习 -- spring中的事件机制
- 【spring源码学习】spring的事件发布监听机制源码解析
- springboot学习----事件监听
- Spring 注解学习手札(四) 持久层浅析
- 案例学习BlazeDS+Spring之四InSync02使用RemoteObject事件
- Spring学习笔记(十) --- 浅析Spring MVC的工作机制
- Spring 注解学习手札(四) 持久层浅析
- Spring入门学习——使用应用事件进行通信