Spring源码分析之组件扫描事件监听处理器

本文探讨了如何在Spring框架中使用JPA注册持久化bean处理器,以及如何注册事件监听处理器类和默认事件监听器工厂。通过检查JPA支持并确保必要的bean定义不存在,系统将自动添加这些组件。

判断是否支持JPA来注册持久化bean处理器


// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  RootBeanDefinition def = new RootBeanDefinition();
  try {
    def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
        AnnotationConfigUtils.class.getClassLoader()));
  }
  catch (ClassNotFoundException ex) {
    throw new IllegalStateException(
        "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
  }
  def.setSource(source);
  beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}

if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
  RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
  def.setSource(source);
  beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
  RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
  def.setSource(source);
  beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}

注册事件监听处理器类EventListenerMethodProcessor,注册默认事件监听器工厂


if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
  RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
  def.setSource(source);
  beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
  RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
  def.setSource(source);
  beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}

它实现了接口SmartInitializingSingleton,在容器初始化最后会触发方法afterSingletonsInstantiated


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) {
        // 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) {
        if (ScopedObject.class.isAssignableFrom(type)) {
          try {
            type = AutoProxyUtils.determineTargetClass(this.applicationContext.getBeanFactory(),
                ScopedProxyUtils.getTargetBeanName(beanName));
          }
          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);
        }
      }
    }
  }
}

获取容器上下文中事件监听器工厂类

protected List<EventListenerFactory> getEventListenerFactories() {
  Map<String, EventListenerFactory> beans = this.applicationContext.getBeansOfType(EventListenerFactory.class);
  List<EventListenerFactory> allFactories = new ArrayList<EventListenerFactory>(beans.values());
  AnnotationAwareOrderComparator.sort(allFactories);
  return allFactories;
}

判断bean名字是否是目标代理范围


private static final String TARGET_NAME_PREFIX = "scopedTarget.";
public static boolean isScopedTarget(String beanName) {
  return (beanName != null && beanName.startsWith(TARGET_NAME_PREFIX));
}

获取bean类型


public static final String ORIGINAL_TARGET_CLASS_ATTRIBUTE =
      Conventions.getQualifiedAttributeName(AutoProxyUtils.class, "originalTargetClass");

public static Class<?> determineTargetClass(ConfigurableListableBeanFactory beanFactory, String beanName) {
  if (beanName == null) {
    return null;
  }
  if (beanFactory.containsBeanDefinition(beanName)) {
    BeanDefinition bd = beanFactory.getMergedBeanDefinition(beanName);
    Class<?> targetClass = (Class<?>) bd.getAttribute(ORIGINAL_TARGET_CLASS_ATTRIBUTE);
    if (targetClass != null) {
      return targetClass;
    }
  }
  return beanFactory.getType(beanName);
}

对bean进行处理,检查类型的方法中是否还有注解EventListener

protected void processBean(final List<EventListenerFactory> factories, final String beanName, final Class<?> targetType) {
  if (!this.nonAnnotatedClasses.contains(targetType)) {
    Map<Method, EventListener> annotatedMethods = null;
    try {
      annotatedMethods = MethodIntrospector.selectMethods(targetType,
          new MethodIntrospector.MetadataLookup<EventListener>() {
            @Override
            public EventListener inspect(Method method) {
              return 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);
      }
    }
    else {
      // 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;
          }
        }
      }
      if (logger.isDebugEnabled()) {
        logger.debug(annotatedMethods.size() + " @EventListener methods processed on bean '" +
            beanName + "': " + annotatedMethods);
      }
    }
  }
}

查看监听器工厂是否支持该方法,然后创建对应的上下文监听器

public ApplicationListener<?> createApplicationListener(String beanName, Class<?> type, Method method) {
  return new ApplicationListenerMethodAdapter(beanName, type, method);
}

public ApplicationListenerMethodAdapter(String beanName, Class<?> targetClass, Method method) {
  this.beanName = beanName;
  this.method = method;
  this.targetClass = targetClass;
  this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);

  EventListener ann = AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class);
  this.declaredEventTypes = resolveDeclaredEventTypes(method, ann);
  this.condition = (ann != null ? ann.condition() : null);
  this.order = resolveOrder(method);

  this.methodKey = new AnnotatedElementKey(method, targetClass);
}

初始化它的上下文属性和事件表达式解析类,最后添加到上下文中

void init(ApplicationContext applicationContext, EventExpressionEvaluator evaluator) {
  this.applicationContext = applicationContext;
  this.evaluator = evaluator;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值