2019独角兽企业重金招聘Python工程师标准>>>
说到前面
本文转自“天河聊技术”微信公众号
本次主要介绍监听器的实例化过程源码解析。
正文
我们跟踪@EventListener源码可以发现,背后的实现是这个类EventListenerMethodProcessor,spring应用上下文启动的时候会加载这个类,我看下这个类
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> nonAnnotatedClasses = Collections.newSetFromMap(new ConcurrentHashMap<>(64));
这个类中依赖了spring配置上下文对象和表达式解析器对象。
找到这个类实现了父类ApplicationContextAware.setApplicationContext()这个方法,获取spring配置上下文对象。
找到这个方法的实现,所有的单例bean实例化之后会执行这个方法
@Override public void afterSingletonsInstantiated() {//所有的单例bean创建完成后执行这个方法 // 下面开始创建ApplicationListener,获得创建ApplicationListener的工厂集合 Listfactories = 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); } } } } }
重点看下这行代码,实例化监听器的操作在这里
try { processBean(factories, beanName, type); }
protected void processBean( final Listfactories, final String beanName, final Class> targetType) { // 如果目标对象不是注解类型 if (!this.nonAnnotatedClasses.contains(targetType)) { Map annotatedMethods = null; try { // 找到加了@EventListener这个注解的方法 annotatedMethods = MethodIntrospector.selectMethods(targetType, (MethodIntrospector.MetadataLookup ) 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的事件驱动模型发布一个事件的源码解析。