spring源碼解析系列之事件驅動模型@EventListener

說到前面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的事件驅動模型發佈一個事件的源碼解析。

相關文章
相關標籤/搜索