代码:https://github.com/shangjianan2/NormalTechnology.git
EventListener
使用
定义事件
需要继承ApplicationEvent
package com.ework.upms.server.event;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.context.ApplicationEvent;
@Getter
public class UserDTO extends ApplicationEvent {
private Integer userId;
private String name;
private Integer age;
public UserDTO(Object source, Integer userId, String name, Integer age) {
super(source);
this.userId = userId;
this.name = name;
this.age = age;
}
}
监听器
package com.ework.upms.server.event;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
// 通过实现接口实现监听器
@Component
public class UserRegisterEmailListener implements ApplicationListener<UserDTO> {
@Override
public void onApplicationEvent(UserDTO userDTO){
System.out.println("监听到用户注册,准备发送邮件,user:" + userDTO.toString());
}
}
发布事件的服务
package com.ework.upms.server.event;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class UserServiceImpl implements UserService{
@Autowired
private ApplicationEventPublisher eventPublisher;
@Override
public void register(){
UserDTO userDTO = new UserDTO(this, 18, "精灵王jinglingwang.cn", 1001);
// userDTO.setAge(18);
// userDTO.setName("精灵王jinglingwang.cn");
// userDTO.setUserId(1001);
System.out.println("register user");
eventPublisher.publishEvent(userDTO);
}
}
单元测试
package com.ework.upms.server.event;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.annotations.Test;
@ContextConfiguration(locations = {"classpath:spring-servlet.xml"})
public class UserServiceImplTest extends AbstractTestNGSpringContextTests {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private UserService userService;
@Test
public void testUserEvent(){
userService.register();
}
}
分析
调用堆栈
handleUserEvent:15, UserRegisterSmsListener (com.ework.upms.server.event)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
doInvoke:253, ApplicationListenerMethodAdapter (org.springframework.context.event)
processEvent:174, ApplicationListenerMethodAdapter (org.springframework.context.event)
onApplicationEvent:137, ApplicationListenerMethodAdapter (org.springframework.context.event)
invokeListener:167, SimpleApplicationEventMulticaster (org.springframework.context.event)
multicastEvent:139, SimpleApplicationEventMulticaster (org.springframework.context.event)
publishEvent:393, AbstractApplicationContext (org.springframework.context.support)
publishEvent:347, AbstractApplicationContext (org.springframework.context.support)
register:20, UserServiceImpl (com.ework.upms.server.event)
testUserEvent:19, UserServiceImplTest (com.ework.upms.server.event)
multicastEvent:139, SimpleApplicationEventMulticaster (org.springframework.context.event)
中遍历了所有已经注册的且符合事件类型的监听器
@Override
public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {//遍历监听器
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(new Runnable() {
@Override
public void run() {
invokeListener(listener, event);
}
});
}
else {
invokeListener(listener, event);//第139行,运行过程中实际运行的位置
}
}
}
Async+EventListener
待续
TransactionalEventListener
使用这个注解之后,整个事务正常提交之后才会触发事件监听
使用
与EventListener
大致相同。但是要注意,事件触发时需要包装在事务中。
服务
package com.ework.upms.server.service;
import com.ework.upms.server.annotation.MyAnnotation;
import com.ework.upms.server.event.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class TestTransaction {
@Autowired
private UserService userService;
@Transactional(transactionManager = "adsTm")//需要在事务中调用事件
public String helloWorld() {
userService.register();
return "adsf";
}
}
单元测试
package com.ework.upms.server.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.annotations.Test;
@ContextConfiguration(locations = {"classpath:spring-servlet.xml"})
public class testAspectTest extends AbstractTestNGSpringContextTests {
@Autowired
private TestAspect testAspect;
@Autowired
private TestTransaction testTransaction;
@Test
public void test() {
// testAspect.helloWorld();
testTransaction.helloWorld();
}
}
分析
调用堆栈
handleUserEvent:15, UserRegisterSmsListener (com.ework.upms.server.event)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
doInvoke:253, ApplicationListenerMethodAdapter (org.springframework.context.event)
processEvent:174, ApplicationListenerMethodAdapter (org.springframework.context.event)//从此之后与使用EventListener时的调用堆栈相同
processEvent:127, ApplicationListenerMethodTransactionalAdapter$TransactionSynchronizationEventAdapter (org.springframework.transaction.event)
afterCompletion:116, ApplicationListenerMethodTransactionalAdapter$TransactionSynchronizationEventAdapter (org.springframework.transaction.event)
invokeAfterCompletion:168, TransactionSynchronizationUtils (org.springframework.transaction.support)//此处遍历触发事件
invokeAfterCompletion:1002, AbstractPlatformTransactionManager (org.springframework.transaction.support)
triggerAfterCompletion:977, AbstractPlatformTransactionManager (org.springframework.transaction.support)//从ThreadLocal中获取所有事件
processCommit:806, AbstractPlatformTransactionManager (org.springframework.transaction.support)
commit:730, AbstractPlatformTransactionManager (org.springframework.transaction.support)
commitTransactionAfterReturning:504, TransactionAspectSupport (org.springframework.transaction.interceptor)
invokeWithinTransaction:292, TransactionAspectSupport (org.springframework.transaction.interceptor)//事务正常提交之后运行这段代码
invoke:96, TransactionInterceptor (org.springframework.transaction.interceptor)
proceed:179, ReflectiveMethodInvocation (org.springframework.aop.framework)
intercept:673, CglibAopProxy$DynamicAdvisedInterceptor (org.springframework.aop.framework)
helloWorld:-1, TestTransaction$$EnhancerBySpringCGLIB$$7bdc734c (com.ework.upms.server.service)
test:18, testAspectTest (com.ework.upms.server.service)
1、invokeWithinTransaction:292, TransactionAspectSupport (org.springframework.transaction.interceptor)
在事务正常提交之后触发事件监听
protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
throws Throwable {
........................
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// target invocation exception
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
commitTransactionAfterReturning(txInfo);//第292行
return retVal;
}
else {
// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
............................
}
}
2、triggerAfterCompletion:977, AbstractPlatformTransactionManager (org.springframework.transaction.support)
,此处开始使用ThreadLocal
private void triggerAfterCompletion(DefaultTransactionStatus status, int completionStatus) {
if (status.isNewSynchronization()) {
List<TransactionSynchronization> synchronizations = TransactionSynchronizationManager.getSynchronizations();//从ThreadLocal中获取所有事件
TransactionSynchronizationManager.clearSynchronization();
if (!status.hasTransaction() || status.isNewTransaction()) {
if (status.isDebug()) {
logger.trace("Triggering afterCompletion synchronization");
}
// No transaction or new transaction for the current scope ->
// invoke the afterCompletion callbacks immediately
invokeAfterCompletion(synchronizations, completionStatus);//第977行
}
else if (!synchronizations.isEmpty()) {
// Existing transaction that we participate in, controlled outside
// of the scope of this Spring transaction manager -> try to register
// an afterCompletion callback with the existing (JTA) transaction.
registerAfterCompletionWithExistingTransaction(status.getTransaction(), synchronizations);
}
}
}
synchronizations
的声明为private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations = new NamedThreadLocal<Set<TransactionSynchronization>>("Transaction synchronizations");
事件触发时会插入到这个ThreadLocal中
触发前
触发后
之后在TransactionAspectSupport中会调用if (txAttr == null || !(tm instanceof > CallbackPreferringPlatformTransactionManager)) { // Standard transaction demarcation with getTransaction and commit/rollback calls. TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification); Object retVal = null; try { // This is an around advice: Invoke the next interceptor in the chain. // This will normally result in a target object being invoked. retVal = invocation.proceedWithInvocation(); } catch (Throwable ex) { // target invocation exception completeTransactionAfterThrowing(txInfo, ex); throw ex; } finally { cleanupTransactionInfo(txInfo); } commitTransactionAfterReturning(txInfo);//在这里触发 return retVal; }
3、invokeAfterCompletion:168, TransactionSynchronizationUtils (org.springframework.transaction.support)
,遍历事件
public static void invokeAfterCompletion(List<TransactionSynchronization> synchronizations, int completionStatus) {
if (synchronizations != null) {
for (TransactionSynchronization synchronization : synchronizations) {
try {
synchronization.afterCompletion(completionStatus);//第168行,completionStatus=0
}
catch (Throwable tsex) {
logger.error("TransactionSynchronization.afterCompletion threw exception", tsex);
}
}
}
}
4、processEvent:174, ApplicationListenerMethodAdapter (org.springframework.context.event)
,此处之后,与EventListener相同
public void processEvent(ApplicationEvent event) {
Object[] args = resolveArguments(event);//第174行
if (shouldHandle(event, args)) {
Object result = doInvoke(args);
if (result != null) {
handleResult(result);
}
else {
logger.trace("No result object given - no result to handle");
}
}
}
多个Listener
this.eventPublisher.applicationEventMulticaster.defaultRetriever.applicationListeners中记录所有的listener
multicastEvent:139, SimpleApplicationEventMulticaster (org.springframework.context.event)
中遍历了所有已经注册的且符合事件类型的监听器
而过滤出监听器的责任由getApplicationListeners
负责
public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
//下面getApplicationListeners将符合要求的监听器过滤出来
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(new Runnable() {
@Override
public void run() {
invokeListener(listener, event);
}
});
}
else {
invokeListener(listener, event);
}
}
}
retrieveApplicationListeners:220, AbstractApplicationEventMulticaster (org.springframework.context.event)//遍历所有监听器,寻找符合要求的
getApplicationListeners:192, AbstractApplicationEventMulticaster (org.springframework.context.event)
multicastEvent:128, SimpleApplicationEventMulticaster (org.springframework.context.event)
publishEvent:393, AbstractApplicationContext (org.springframework.context.support)
publishEvent:347, AbstractApplicationContext (org.springframework.context.support)
publish:14, MyEventPublisher (com.ework.upms.server.event.event2)
test:21, MyEventTest (com.ework.upms.server.event.event2)
retrieveApplicationListeners:220, AbstractApplicationEventMulticaster (org.springframework.context.event)
从上下文中遍历出所有符合要求的,然后在multicastEvent:128, SimpleApplicationEventMulticaster (org.springframework.context.event)
中触发。
SqlSessionFactoryBean好像是所有事件的监听器