Spring @EventListener 加载流程

Spring 面试 About 6,463 words

注解

/**
 * @see EventListenerMethodProcessor
 */
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EventListener {

    @AliasFor("classes")
    Class<?>[] value() default {};

    @AliasFor("value")
    Class<?>[] classes() default {};

    String condition() default "";

}

原理

EventListenerMethodProcessor后置处理器实现了SmartInitializingSingleton接口,afterSingletonsInstantiated调用时机是在bean初始化完成后。

public interface SmartInitializingSingleton {

    void afterSingletonsInstantiated();

}

public class EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware {
    @Override
    public void afterSingletonsInstantiated() {
        List<EventListenerFactory> factories = getEventListenerFactories();
        // 获取所有 BeanFactory 中的 bean
        String[] beanNames = this.applicationContext.getBeanNamesForType(Object.class);
        for (String beanName : beanNames) {
            // 找到标注了
            processBean(factories, beanName, type);
        }
    }

    protected void processBean(final List<EventListenerFactory> factories, final String beanName, final Class<?> targetType) {

        Map<Method, EventListener> annotatedMethods = null;
        try {
            // 找到标注了 @EventListener 的方法
            annotatedMethods = MethodIntrospector.selectMethods(targetType,
                    new MethodIntrospector.MetadataLookup<EventListener>() {
                        @Override
                        public EventListener inspect(Method method) {
                            return AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class);
                        }
                    });
        }
        catch (Throwable ex) {

        }

        // 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<?> applicationListener = factory.createApplicationListener(beanName, targetType, methodToUse);
                    if (applicationListener instanceof ApplicationListenerMethodAdapter) {
                        ((ApplicationListenerMethodAdapter) applicationListener).init(this.applicationContext, this.evaluator);
                    }
                    // 加入到监听器容器中
                    this.applicationContext.addApplicationListener(applicationListener);
                    break;
                }
            }
        }

    }
}

// 创建 ApplicationListener 对象
public class DefaultEventListenerFactory implements EventListenerFactory, Ordered {
    @Override
    public ApplicationListener<?> createApplicationListener(String beanName, Class<?> type, Method method) {
        return new ApplicationListenerMethodAdapter(beanName, type, method);
    }
}

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

        Method targetMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
        EventListener ann = AnnotatedElementUtils.findMergedAnnotation(targetMethod, EventListener.class);

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

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

afterSingletonsInstantiated调用时机。

public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean {

    @Override
    public void refresh() throws BeansException, IllegalStateException {
        // Instantiate all remaining (non-lazy-init) singletons.
        finishBeanFactoryInitialization(beanFactory);

    }

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // Instantiate all remaining (non-lazy-init) singletons.
        beanFactory.preInstantiateSingletons();
    }
}

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
    @Override
    public void preInstantiateSingletons() throws BeansException {

        List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

        // Trigger initialization of all non-lazy singleton beans...
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                    // 初始化实现了 FactoryBean 接口的对象
                }
                else {
                    // 初始化普通 bean,如标注了 @Component @Service 注解的对象
                    getBean(beanName);
                }
            }
        }

        // 初始化完成后的回调
        // Trigger post-initialization callback for all applicable beans...
        for (String beanName : beanNames) {
            Object singletonInstance = getSingleton(beanName);
            if (singletonInstance instanceof SmartInitializingSingleton) {
                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                // 回调
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}

完整调用栈

processBean:159, EventListenerMethodProcessor (org.springframework.context.event)
afterSingletonsInstantiated:104, EventListenerMethodProcessor (org.springframework.context.event)
preInstantiateSingletons:781, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:867, AbstractApplicationContext (org.springframework.context.support)
refresh:543, AbstractApplicationContext (org.springframework.context.support)
main:28, Test7 (com.example.learn)
Views: 1,959 · Posted: 2021-12-19

————        END        ————

Give me a Star, Thanks:)

https://github.com/fendoudebb/LiteNote

扫描下方二维码关注公众号和小程序↓↓↓

扫描下方二维码关注公众号和小程序↓↓↓


Today On History
Browsing Refresh