說到前面spring
本文轉自「天河聊技術」微信公衆號微信
本次主要介紹監聽器的實例化過程源碼解析。併發
正文app
咱們跟蹤@EventListener源碼能夠發現,背後的實現是這個類EventListenerMethodProcessor,spring應用上下文啓動的時候會加載這個類,我看下這個類ide
public class EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware { protected final Log logger = LogFactory.getLog(getClass()); @Nullable private ConfigurableApplicationContext applicationContext; private final EventExpressionEvaluator evaluator = new EventExpressionEvaluator(); // 增長map的默認併發數,能夠減小map的自動擴容次數,必定程度上會提升程序的性能 private final Set<Class<?>> nonAnnotatedClasses = Collections.newSetFromMap(new ConcurrentHashMap<>(64));
這個類中依賴了spring配置上下文對象和表達式解析器對象。性能
找到這個類實現了父類ApplicationContextAware.setApplicationContext()這個方法,獲取spring配置上下文對象。this
找到這個方法的實現,全部的單例bean實例化以後會執行這個方法lua
@Override public void afterSingletonsInstantiated() {//全部的單例bean建立完成後執行這個方法 // 下面開始建立ApplicationListener,得到建立ApplicationListener的工廠集合 List<EventListenerFactory> factories = getEventListenerFactories(); // 得到配置上下文對象 ConfigurableApplicationContext context = getApplicationContext(); // 得到bean的名字 String[] beanNames = context.getBeanNamesForType(Object.class); for (String beanName : beanNames) { if (!ScopedProxyUtils.isScopedTarget(beanName)) { Class<?> type = null; try { // 獲取bean的初始目標類的類型 type = AutoProxyUtils.determineTargetClass(context.getBeanFactory(), beanName); } catch (Throwable ex) { // An unresolvable bean type, probably from a lazy bean - let's ignore it. if (logger.isDebugEnabled()) { logger.debug("Could not resolve target class for bean with name '" + beanName + "'", ex); } } if (type != null) { // type表示的類或接口的超類或超接口是否和ScopedObject同樣 if (ScopedObject.class.isAssignableFrom(type)) { try { Class<?> targetClass = AutoProxyUtils.determineTargetClass( context.getBeanFactory(), ScopedProxyUtils.getTargetBeanName(beanName)); if (targetClass != null) { type = targetClass; } } catch (Throwable ex) { // An invalid scoped proxy arrangement - let's ignore it. if (logger.isDebugEnabled()) { logger.debug("Could not resolve target bean for scoped proxy '" + beanName + "'", ex); } } } try { processBean(factories, beanName, type); } catch (Throwable ex) { throw new BeanInitializationException("Failed to process @EventListener " + "annotation on bean with name '" + beanName + "'", ex); } } } } }
重點看下這行代碼,實例化監聽器的操做在這裏debug
try { processBean(factories, beanName, type); }
protected void processBean( final List<EventListenerFactory> factories, final String beanName, final Class<?> targetType) { // 若是目標對象不是註解類型 if (!this.nonAnnotatedClasses.contains(targetType)) { Map<Method, EventListener> annotatedMethods = null; try { // 找到加了@EventListener這個註解的方法 annotatedMethods = MethodIntrospector.selectMethods(targetType, (MethodIntrospector.MetadataLookup<EventListener>) method -> AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class)); } catch (Throwable ex) { // An unresolvable type in a method signature, probably from a lazy bean - let's ignore it. if (logger.isDebugEnabled()) { logger.debug("Could not resolve methods for bean with name '" + beanName + "'", ex); } } if (CollectionUtils.isEmpty(annotatedMethods)) { this.nonAnnotatedClasses.add(targetType); if (logger.isTraceEnabled()) { logger.trace("No @EventListener annotations found on bean class: " + targetType.getName()); } } else { // Non-empty set of methods 獲取配置上下文對象 ConfigurableApplicationContext context = getApplicationContext(); for (Method method : annotatedMethods.keySet()) { for (EventListenerFactory factory : factories) { if (factory.supportsMethod(method)) { // 獲取可調用的方法 Method methodToUse = AopUtils.selectInvocableMethod(method, context.getType(beanName)); // 建立applicationListener對象,返回的是GenericApplicationListener的adaptor ApplicationListenerMethodAdapter對象 ApplicationListener<?> applicationListener = factory.createApplicationListener(beanName, targetType, methodToUse); if (applicationListener instanceof ApplicationListenerMethodAdapter) { // 若是applicationListenr的具體類型是ApplicationListenerMethodAdapter,就進行初始化 ((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator); } // 若是applicationListenr的具體類型是ApplicationListenerMethodTransactionalAdapter,把這個監聽器配置到spring配置上下文中 context.addApplicationListener(applicationListener); break; } } } if (logger.isDebugEnabled()) { logger.debug(annotatedMethods.size() + " @EventListener methods processed on bean '" + beanName + "': " + annotatedMethods); } } } }
看下這行代碼的背後實現對象
若是applicationListenr的具體類型是ApplicationListenerMethodTransactionalAdapter,把這個監聽器配置到spring配置上下文中,這個監聽器類型是支持事務的監聽器,在spring-tx包源碼解析中會具體解析 context.addApplicationListener(applicationListener);
@Override public void addApplicationListener(ApplicationListener<?> listener) { Assert.notNull(listener, "ApplicationListener must not be null"); if (this.applicationEventMulticaster != null) { // 若是事件發佈管理器不爲空,就把這個監聽器添加到其中 this.applicationEventMulticaster.addApplicationListener(listener); } else { // 把監聽器發佈到spring上下文中 this.applicationListeners.add(listener); } }
建立完applicationListener的adaptor對象後,注入到事件發佈管理器中或者spring上下文中。
說到最後
本次介紹就這些,下次介紹基於spring的事件驅動模型發佈一個事件的源碼解析。