您的位置:首页 > 编程语言 > Java开发

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息