1、監聽器實現
實現ApplicationListener接口:
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
public class MyApplicationListener implements ApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("事件"+event);
}
}
使用@EventListener注解
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class MyServiceListener {
@EventListener(classes = ApplicationEvent.class)
public void myService(ApplicationEvent event){
System.out.println("MyServiceListener類接收事件:"+ event);
}
}
2、源碼解析前需要了解的事件發布工具類:ApplicationEventMulticaster接口
ApplicationEventMulticaster接口的實現類可以管理大量ApplicationListener對象並向其發布事件。
相關方法:
void addApplicationListener(ApplicationListener<?> listener); (添加一個偵聽器以通知所有事件。)
void addApplicationListenerBean(String listenerBeanName);(添加一個偵聽器以通知所有事件。)
void multicastEvent(ApplicationEvent event);(將給定的應用程序事件多播到適當的偵聽器。)
void multicastEvent(ApplicationEvent event, ResolvableType eventType);
該工具類注入方式:refresh(); --> initApplicationEventMulticaster();
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
(APPLICATION_EVENT_MULTICASTER_BEAN_NAME=“applicationEventMulticaster”)
3、實現ApplicationListener接口方式注入監聽器相關源碼解析:
1)、向ApplicationEventMulticaster接口(AbstractApplicationEventMulticaster實現類)添加實現ApplicationListener接口的監聽器
refresh(); (AnnotationConfigApplicationContext.java)
registerListeners(); (AbstractApplicationContext.java)
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames){
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
2)spring框架注入的內部類:ApplicationListenerDetector.java (添加實現ApplicationListener接口的監聽器)
注入位置:refresh(); ---->prepareBeanFactory(beanFactory);------->beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
作用:創建實現ApplicationListener接口的監聽器時,需遍歷已經注入的后置處理器(beanPostProcessors),該后置處理器向applicationContext類注入該監聽類

即:ApplicationListenerDetector.java:this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
--->AbstractApplicationContext.java:this.applicationEventMulticaster.addApplicationListener(listener);
---->AbstractApplicationEventMulticaster.java:this.defaultRetriever.applicationListeners.add(listener);
3、使用@EventListener注解的注入監聽器相關源碼解析
相關知識點:Class類中的getMethods(),該方法是獲取本類以及父類或者父接口中所有的公共方法(public修飾符修飾的)。
Class類中的getDeclaredMethods(),該方法是獲取本類中的所有方法,包括私有的(private、protected、默認以及public)的方法。
Class類中的getInterfaces(),能夠獲得這個對象所實現的所有接口。
Method類中getModifiers(),返回此類或接口以整數編碼的 Java 語言修飾符。如需要知道返回的值所代表的意思,則需要用到 java.lang.reflect.Modifier 這個類,這個類提供了 static 方法和常量,可以對類和成員訪問修飾符進行解碼。
Method.getAnnotation(Class <T> annotationClass)方法如果存在這樣的注釋,則返回指定類型的元素的注釋,否則為null。
Class1.isAssignableFrom(Class2),是用來判斷一個類Class1和另一個類Class2是否相同或者Class1類是不是Class2的父類。
關鍵類:org.springframework.context.event.internalEventListenerProcessor(實現類:org.springframework.context.event.EventListenerMethodProcessor)
注入位置:
this(); (AnnotationConfigApplicationContext.java)
----> this.reader = new AnnotatedBeanDefinitionReader(this); (AnnotationConfigApplicationContext.java)
----->this(registry, getOrCreateEnvironment(registry)); (AnnotatedBeanDefinitionReader.java)
----->AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); (AnnotatedBeanDefinitionReader.java)
----->registerAnnotationConfigProcessors(registry, null); (AnnotationConfigUtils.java)
(在給定的注冊表中注冊所有相關的注釋后處理器)

EventListenerMethodProcessor作用:
使用EventListenerMethodProcessor處理器來解析方法上的@EventListener:
public void afterSingletonsInstantiated()
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
EventListenerMethodProcessor.java------> smartSingleton.afterSingletonsInstantiated() :
@Override
public void afterSingletonsInstantiated() {
List<EventListenerFactory> factories = getEventListenerFactories();
String[] beanNames = this.applicationContext.getBeanNamesForType(Object.class);
for (String beanName : beanNames) {
if (!ScopedProxyUtils.isScopedTarget(beanName)) {
Class<?> type = null;
try {
type = AutoProxyUtils.determineTargetClass(this.applicationContext.getBeanFactory(), beanName);
}
catch (Throwable ex) {
}
if (type != null) {
try {
processBean(factories, beanName, type);
}
catch (Throwable ex) {
throw new BeanInitializationException("Failed to process @EventListener " +
"annotation on bean with name '" + beanName + "'", ex);
}
}
}
}
}
EventListenerMethodProcessor.java------>processBean(factories, beanName, type)。
覆寫了MetadataLookup對象的inspect(Method method)方法。
inspect(Method method)方法:AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class);改操作判斷方法是否有@EventListener注解。如果存在這樣的注釋,則返回指定類型的元素的注釋,否則為null。
AnnotationConfigUtils.registerAnnotationConfigProcessors(registry, null)方法會為容器注入名為org.springframework.context.event.internalEventListenerFactory,類型為DefaultEventListenerFactory.java,該類的方法:public ApplicationListener<?> createApplicationListener(String beanName, Class<?> type, Method method),其根據類名,類的class,方法(有@EventListener注解),來構建一個監聽器。
protected void processBean(final List<EventListenerFactory> factories, final String beanName, final Class<?> targetType) {
//.........................
Map<Method, EventListener> annotatedMethods = null;//存放所有有@EventListener注解的方法
annotatedMethods = MethodIntrospector.selectMethods(targetType,
new MethodIntrospector.MetadataLookup<EventListener>() {
@Override
public EventListener inspect(Method method) {
return AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class);
}
});
//.......................................
// Non-empty set of methods
for (Method method : annotatedMethods.keySet()) {
for (EventListenerFactory factory : factories) {
if (factory.supportsMethod(method)) {
Method methodToUse = AopUtils.selectInvocableMethod(
method, this.applicationContext.getType(beanName));
ApplicationListener<?> applicationListener =
factory.createApplicationListener(beanName, targetType, methodToUse);
if (applicationListener instanceof ApplicationListenerMethodAdapter) {
((ApplicationListenerMethodAdapter) applicationListener)
.init(this.applicationContext, this.evaluator);
}
this.applicationContext.addApplicationListener(applicationListener);
break;
}
}
}
}
MethodIntrospector.java ---------> selectMethods()
覆寫了MethodCallback對象的doWith(Method method)方法。
在doWith方法中,T result = metadataLookup.inspect(specificMethod); 會調用上面被覆寫的inspect方法來判斷方法是否有@EventListener注解。
public static <T> Map<Method, T> selectMethods(Class<?> targetType, final MetadataLookup<T> metadataLookup) {
final Map<Method, T> methodMap = new LinkedHashMap<Method, T>();//存放所有有@EventListener注解的方法
Set<Class<?>> handlerTypes = new LinkedHashSet<Class<?>>();
handlerTypes.addAll(Arrays.asList(targetType.getInterfaces()));
for (Class<?> currentHandlerType : handlerTypes) {//遍歷本類或父接口
final Class<?> targetClass = (specificHandlerType != null ? specificHandlerType : currentHandlerType);
ReflectionUtils.doWithMethods(currentHandlerType, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) {
Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
T result = metadataLookup.inspect(specificMethod);
if (result != null) {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
if (bridgedMethod == specificMethod || metadataLookup.inspect(bridgedMethod) == null) {
methodMap.put(specificMethod, result);
}
}
}
}, ReflectionUtils.USER_DECLARED_METHODS);
}
return methodMap;
}
void doWithMethods(Class<?> clazz, MethodCallback mc, MethodFilter mf),循環遍歷該類的全部方法,將method當做方法參數調用dowith方法。
public static void doWithMethods(Class<?> clazz, MethodCallback mc, MethodFilter mf) {
// Keep backing up the inheritance hierarchy.
Method[] methods = getDeclaredMethods(clazz);//獲取該類的全部方法
for (Method method : methods) {
if (mf != null && !mf.matches(method)) {
continue;
}
try {
mc.doWith(method);
}
catch (IllegalAccessException ex) {
throw new IllegalStateException("Not allowed to access method '" + method.getName() + "': " + ex);
}
}
if (clazz.getSuperclass() != null) {
doWithMethods(clazz.getSuperclass(), mc, mf);
}
else if (clazz.isInterface()) {
for (Class<?> superIfc : clazz.getInterfaces()) {
doWithMethods(superIfc, mc, mf);
}
}
}
4、發布事件相關源碼解析:
annotationConfigApplicationContext.publishEvent(new MyApplicationEvent("yhq"));
----> publishEvent(event, null); (AbstractApplicationContext.java)
----->getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType); (AbstractApplicationContext.java)
------>(SimpleApplicationEventMulticaster.java):
@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);
}
}
}
------> getApplicationListeners(event, type) (AbstractApplicationEventMulticaster.java)//獲取全部類型匹配的listener
------> Collection<ApplicationListener<?>> listeners = retrieveApplicationListeners(eventType, sourceType, retriever); //檢查listener是否匹配。
------>invokeListener(listener, event);
------>listener.onApplicationEvent(event);
----->this.bridgedMethod.invoke(bean, args);
