• BeanFactory后置处理器


    EventListenerMethodProcessor 是 BeanFactory 的一个后置处理器, 用来对 @EventListener 提供支持.

    主要是标注了 @EventListener 的方法进行解析, 然后转换为一个 ApplicationListener.

    1. 在 refresh 容器的时候, 调用 invokeBeanFactoryPostProcessors() 方法时, 会执行 BeanFactoryPostProcessor#postProcessBeanFactory() 方法.

      此方法中, 他只是设置了一个默认的监听器工厂 : DefaultEventListenerFactory

    2. 他实现了 SmartInitializingSingleton 接口, 会在

      org.springframework.context.support.AbstractApplicationContext#refresh

      |/

      org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization

      |/

      org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons 方法中调用其 afterSingletonsInstantiated() 方法.

      其调用时机是, 遍历容器中注册的 BeanDefinition, 调用所有 getBean() 方法之后, 才会开始遍历执行 afterSingletonsInstantiated() 方法.

      这里最终会调用 processBean() 方法.

      此方法中, 就会去容器中查找标注了 @EventListener 注解的方法, 然后进行转换.

    /**
     * 这个后置处理器, 主要是处理 @EventListener 注解的.
     * 1. 解析 @EventListener , 获取拦截方法
     * 2. 对拦截方法进行转换, 变成 ApplicationListener
     * 3. 将转换的 ApplicationListener, 放到spring容器中
     * Registers {@link EventListener} methods as individual {@link ApplicationListener} instances.
     * Implements {@link BeanFactoryPostProcessor} (as of 5.1) primarily for early retrieval,
     * avoiding AOP checks for this processor bean and its {@link EventListenerFactory} delegates.
     *
     * @author Stephane Nicoll
     * @author Juergen Hoeller
     * @since 4.2
     * @see EventListenerFactory
     * @see DefaultEventListenerFactory
     */
    public class EventListenerMethodProcessor
            implements SmartInitializingSingleton, ApplicationContextAware, BeanFactoryPostProcessor {
    
        protected final Log logger = LogFactory.getLog(getClass());
    
        @Nullable
        private ConfigurableApplicationContext applicationContext;
    
        @Nullable
        private ConfigurableListableBeanFactory beanFactory;
    
        @Nullable
        private List<EventListenerFactory> eventListenerFactories;
    
        private final EventExpressionEvaluator evaluator = new EventExpressionEvaluator();
    
        private final Set<Class<?>> nonAnnotatedClasses = Collections.newSetFromMap(new ConcurrentHashMap<>(64));
    
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) {
            Assert.isTrue(applicationContext instanceof ConfigurableApplicationContext,
                    "ApplicationContext does not implement ConfigurableApplicationContext");
            this.applicationContext = (ConfigurableApplicationContext) applicationContext;
        }
    
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
            this.beanFactory = beanFactory;
    
            Map<String, EventListenerFactory> beans = beanFactory.getBeansOfType(EventListenerFactory.class, false, false);
            List<EventListenerFactory> factories = new ArrayList<>(beans.values());
            AnnotationAwareOrderComparator.sort(factories);
            //DefaultEventListenerFactory
            this.eventListenerFactories = factories;
        }
    
    
        @Override
        public void afterSingletonsInstantiated() {
            ConfigurableListableBeanFactory beanFactory = this.beanFactory;
            Assert.state(this.beanFactory != null, "No ConfigurableListableBeanFactory set");
            String[] beanNames = beanFactory.getBeanNamesForType(Object.class);
            for (String beanName : beanNames) {
                if (!ScopedProxyUtils.isScopedTarget(beanName)) {
                    Class<?> type = null;
                    try {
                        type = AutoProxyUtils.determineTargetClass(beanFactory, 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 {
                                Class<?> targetClass = AutoProxyUtils.determineTargetClass(
                                        beanFactory, 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(beanName, type);
                        }
                        catch (Throwable ex) {
                            throw new BeanInitializationException("Failed to process @EventListener " +
                                    "annotation on bean with name '" + beanName + "'", ex);
                        }
                    }
                }
            }
        }
    
        private void processBean(final String beanName, final Class<?> targetType) {
            if (!this.nonAnnotatedClasses.contains(targetType) &&
                    !targetType.getName().startsWith("java") &&
                    !isSpringContainerClass(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 = this.applicationContext;
                    Assert.state(context != null, "No ApplicationContext set");
                    List<EventListenerFactory> factories = this.eventListenerFactories;
                    Assert.state(factories != null, "EventListenerFactory List not initialized");
                    for (Method method : annotatedMethods.keySet()) {
                        for (EventListenerFactory factory : factories) {
                            if (factory.supportsMethod(method)) {
                                Method methodToUse = AopUtils.selectInvocableMethod(method, context.getType(beanName));
                                //为监听方法创建 ApplicationListener
                                ApplicationListener<?> applicationListener =
                                        factory.createApplicationListener(beanName, targetType, methodToUse);
                                if (applicationListener instanceof ApplicationListenerMethodAdapter) {
                                    ((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator);
                                }
                                //将创建的 ApplicationListener 加入到容器中
                                context.addApplicationListener(applicationListener);
                                break;
                            }
                        }
                    }
                    if (logger.isDebugEnabled()) {
                        logger.debug(annotatedMethods.size() + " @EventListener methods processed on bean '" +
                                beanName + "': " + annotatedMethods);
                    }
                }
            }
        }
    
        /**
         * Determine whether the given class is an {@code org.springframework}
         * bean class that is not annotated as a user or test {@link Component}...
         * which indicates that there is no {@link EventListener} to be found there.
         * @since 5.1
         */
        private static boolean isSpringContainerClass(Class<?> clazz) {
            return (clazz.getName().startsWith("org.springframework.") &&
                    !AnnotatedElementUtils.isAnnotated(ClassUtils.getUserClass(clazz), Component.class));
        }
    
    }
  • 相关阅读:
    CSS预编译:less入门
    JavaScript学习(五):函数表达式
    关于JavaScript new 的一些疑问
    JavaScript学习(四):面对对象的程序设计
    JavaScript学习(三):引用类型
    JavaScript学习(二):变量、作用域和内存问题
    JavaScript学习(一):基本概念
    匿名函数的this指向为什么是window?
    阿里云ECS在CentOS 6.8中使用Nginx提示:nginx: [emerg] socket() [::]:80 failed (97: Address family not supported by protocol)的解决方法
    Centos释放缓存
  • 原文地址:https://www.cnblogs.com/elvinle/p/13298007.html
Copyright © 2020-2023  润新知