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);