美文网首页
Spring IOC容器之AnnotationConfigApp

Spring IOC容器之AnnotationConfigApp

作者: 第二人生_c31b | 来源:发表于2019-12-16 20:20 被阅读0次

    AnnotationConfigApplicationContext实现了ApplicationContext接口,提供了基于注解的方式来配置容器。
    AnnotationConfigApplicationContext 的一般使用方法

    public class App {
      public static void main(String[] args) {
        // 1. 初始化AnnotationConfigApplicationContext
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        // 2. 调用register方法注册配置类
        ctx.register(AppConfig.class);
        // 3. 调用refresh方法刷新容器
        ctx.refresh();
      }
    }
    

    AnnotationConfigApplicationContext的初始化

    可以看到,整个容器的创建代码很简单,只需要三行代码就可以创建出一个ApplicationContext。下面我们就跟进AnnotationConfigApplicationContext.java源码,来探索容器是怎么初始化的吧。

    package org.springframework.context.annotation;
    
    import java.util.function.Supplier;
    
    import org.springframework.beans.factory.config.BeanDefinitionCustomizer;
    import org.springframework.beans.factory.support.BeanNameGenerator;
    import org.springframework.beans.factory.support.DefaultListableBeanFactory;
    import org.springframework.context.support.GenericApplicationContext;
    import org.springframework.core.env.ConfigurableEnvironment;
    import org.springframework.lang.Nullable;
    import org.springframework.util.Assert;
    
    /**
     * 独立的 application context,接收一个被注解的类作为输入 - 通常是被@Configuration注解标注的类,
     * 同时也支持@Component类型和使用JSR-330 inject相关注解的类。
     * 可以通过调用register(Class...)方法来向容器中注册类,同时也可以通过调路径用scan方法进行类
     * 扫描注册类。(这里的注册class其实是指根据class对象向容器中注册对应的beanDefinition)
     * 
     * Standalone application context, accepting annotated classes as input - in particular
     * {@link Configuration @Configuration}-annotated classes, but also plain
     * {@link org.springframework.stereotype.Component @Component} types and JSR-330 compliant
     * classes using {@code javax.inject} annotations. Allows for registering classes one by
     * one using {@link #register(Class...)} as well as for classpath scanning using
     * {@link #scan(String...)}.
     *
     * <p>In case of multiple {@code @Configuration} classes, @{@link Bean} methods defined in
     * later classes will override those defined in earlier classes. This can be leveraged to
     * deliberately override certain bean definitions via an extra {@code @Configuration}
     * class.
     *
     * <p>See @{@link Configuration}'s javadoc for usage examples.
     *
     * @author Juergen Hoeller
     * @author Chris Beams
     * @since 3.0
     * @see #register
     * @see #scan
     * @see AnnotatedBeanDefinitionReader
     * @see ClassPathBeanDefinitionScanner
     * @see org.springframework.context.support.GenericXmlApplicationContext
     */
    public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
    
        private final AnnotatedBeanDefinitionReader reader;
    
        private final ClassPathBeanDefinitionScanner scanner;
    
    
        /**
         * Create a new AnnotationConfigApplicationContext that needs to be populated
         * through {@link #register} calls and then manually {@linkplain #refresh refreshed}.
         */
        public AnnotationConfigApplicationContext() {
            // AnnotationConfigApplicationContext支持两种方式读取注册beanDefinition,AnnotatedBeanDefinitionReader用于扫描被@Configuration注解的类
            // ClassPathBeanDefinitionScanner用于注册被@Component、@Service、@Repository、@Controller注解的类
            // 初始化AnnotationConfigApplicationContext会先初始化它的父类,在GenericApplicationContext初始化时,会生成一个DefaultListableBeanFactory
            this.reader = new AnnotatedBeanDefinitionReader(this);
            this.scanner = new ClassPathBeanDefinitionScanner(this);
        }
    
        /**
         * Create a new AnnotationConfigApplicationContext with the given DefaultListableBeanFactory.
         * @param beanFactory the DefaultListableBeanFactory instance to use for this context
         */
        public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory) {
            super(beanFactory);
            this.reader = new AnnotatedBeanDefinitionReader(this);
            this.scanner = new ClassPathBeanDefinitionScanner(this);
        }
    
        /**
         * Create a new AnnotationConfigApplicationContext, deriving bean definitions
         * from the given annotated classes and automatically refreshing the context.
         * @param annotatedClasses one or more annotated classes,
         * e.g. {@link Configuration @Configuration} classes
         */
        public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
            this();
            register(annotatedClasses);
            refresh();
        }
    
        /**
         * Create a new AnnotationConfigApplicationContext, scanning for bean definitions
         * in the given packages and automatically refreshing the context.
         * @param basePackages the packages to check for annotated classes
         */
        public AnnotationConfigApplicationContext(String... basePackages) {
            this();
            scan(basePackages);
            refresh();
        }
    
    
        /**
         * Propagates the given custom {@code Environment} to the underlying
         * {@link AnnotatedBeanDefinitionReader} and {@link ClassPathBeanDefinitionScanner}.
         */
        @Override
        public void setEnvironment(ConfigurableEnvironment environment) {
            super.setEnvironment(environment);
            this.reader.setEnvironment(environment);
            this.scanner.setEnvironment(environment);
        }
    
        /**
         * Provide a custom {@link BeanNameGenerator} for use with {@link AnnotatedBeanDefinitionReader}
         * and/or {@link ClassPathBeanDefinitionScanner}, if any.
         * <p>Default is {@link org.springframework.context.annotation.AnnotationBeanNameGenerator}.
         * <p>Any call to this method must occur prior to calls to {@link #register(Class...)}
         * and/or {@link #scan(String...)}.
         * @see AnnotatedBeanDefinitionReader#setBeanNameGenerator
         * @see ClassPathBeanDefinitionScanner#setBeanNameGenerator
         */
        public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
            this.reader.setBeanNameGenerator(beanNameGenerator);
            this.scanner.setBeanNameGenerator(beanNameGenerator);
            getBeanFactory().registerSingleton(
                    AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator);
        }
    
        /**
         * Set the {@link ScopeMetadataResolver} to use for detected bean classes.
         * <p>The default is an {@link AnnotationScopeMetadataResolver}.
         * <p>Any call to this method must occur prior to calls to {@link #register(Class...)}
         * and/or {@link #scan(String...)}.
         */
        public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {
            this.reader.setScopeMetadataResolver(scopeMetadataResolver);
            this.scanner.setScopeMetadataResolver(scopeMetadataResolver);
        }
    
    
        //---------------------------------------------------------------------
        // Implementation of AnnotationConfigRegistry
        //---------------------------------------------------------------------
    
        /**
         * Register one or more annotated classes to be processed.
         * <p>Note that {@link #refresh()} must be called in order for the context
         * to fully process the new classes.
         * @param annotatedClasses one or more annotated classes,
         * e.g. {@link Configuration @Configuration} classes
         * @see #scan(String...)
         * @see #refresh()
         */
        public void register(Class<?>... annotatedClasses) {
            Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
            // 将配置类注册到容器中
            this.reader.register(annotatedClasses);
        }
    
        /**
         * Perform a scan within the specified base packages.
         * <p>Note that {@link #refresh()} must be called in order for the context
         * to fully process the new classes.
         * @param basePackages the packages to check for annotated classes
         * @see #register(Class...)
         * @see #refresh()
         */
        public void scan(String... basePackages) {
            Assert.notEmpty(basePackages, "At least one base package must be specified");
            this.scanner.scan(basePackages);
        }
    
    
        //---------------------------------------------------------------------
        // Convenient methods for registering individual beans
        //---------------------------------------------------------------------
    
        /**
         * Register a bean from the given bean class, deriving its metadata from
         * class-declared annotations, and optionally providing explicit constructor
         * arguments for consideration in the autowiring process.
         * <p>The bean name will be generated according to annotated component rules.
         * @param annotatedClass the class of the bean
         * @param constructorArguments argument values to be fed into Spring's
         * constructor resolution algorithm, resolving either all arguments or just
         * specific ones, with the rest to be resolved through regular autowiring
         * (may be {@code null} or empty)
         * @since 5.0
         */
        public <T> void registerBean(Class<T> annotatedClass, Object... constructorArguments) {
            registerBean(null, annotatedClass, constructorArguments);
        }
    
        /**
         * Register a bean from the given bean class, deriving its metadata from
         * class-declared annotations, and optionally providing explicit constructor
         * arguments for consideration in the autowiring process.
         * @param beanName the name of the bean (may be {@code null})
         * @param annotatedClass the class of the bean
         * @param constructorArguments argument values to be fed into Spring's
         * constructor resolution algorithm, resolving either all arguments or just
         * specific ones, with the rest to be resolved through regular autowiring
         * (may be {@code null} or empty)
         * @since 5.0
         */
        public <T> void registerBean(@Nullable String beanName, Class<T> annotatedClass, Object... constructorArguments) {
            this.reader.doRegisterBean(annotatedClass, null, beanName, null,
                    bd -> {
                        for (Object arg : constructorArguments) {
                            bd.getConstructorArgumentValues().addGenericArgumentValue(arg);
                        }
                    });
        }
    
        @Override
        public <T> void registerBean(@Nullable String beanName, Class<T> beanClass, @Nullable Supplier<T> supplier,
                BeanDefinitionCustomizer... customizers) {
    
            this.reader.doRegisterBean(beanClass, supplier, beanName, null, customizers);
        }
    
    }
    
    

    AnnotationConfigApplicationContext继承自GenericApplicationContext,这里调用它的默认无参构造方法,会先调用GenericApplicationContext的默认无参构造方法,而GenericApplicationContext在初始化时,会直接生成一个DefaultListableBeanFactory。该beanFactory本身又实现了BeanDefinitionRegistry,有了该beanFactory之后,我们就可以向容器注册beanDefinition了。

    GenericApplicationContext.java

    public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
    
        private final DefaultListableBeanFactory beanFactory;
    
        @Nullable
        private ResourceLoader resourceLoader;
    
        private boolean customClassLoader = false;
    
        private final AtomicBoolean refreshed = new AtomicBoolean();
    
    
        /**
         * Create a new GenericApplicationContext.
         * @see #registerBeanDefinition
         * @see #refresh
         */
        public GenericApplicationContext() {
            this.beanFactory = new DefaultListableBeanFactory();
        }
        ...
    

    继续回到AnnotationConfigApplicationContext的无参构造方法

    public AnnotationConfigApplicationContext() {
        this.reader = new AnnotatedBeanDefinitionReader(this);
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }
    

    这里初始化了AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner,从名字就可以知道,这两个对象是用于读取bean definition的。ClassPathBeanDefinitionScanner是用于scan方法的,而AnnotatedBeanDefinitionReader是用于register方法通过编程方式手动指定注册的类,这里我们只探讨AnnotatedBeanDefinitionReader。

    我们再看一下AnnotatedBeanDefinitionReader初始化时做了一些什么工作。

    AnnotatedBeanDefinitionReader.java

    package org.springframework.context.annotation;
    
    import java.lang.annotation.Annotation;
    import java.util.function.Supplier;
    
    import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
    import org.springframework.beans.factory.config.BeanDefinition;
    import org.springframework.beans.factory.config.BeanDefinitionCustomizer;
    import org.springframework.beans.factory.config.BeanDefinitionHolder;
    import org.springframework.beans.factory.support.AutowireCandidateQualifier;
    import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.beans.factory.support.BeanNameGenerator;
    import org.springframework.core.env.Environment;
    import org.springframework.core.env.EnvironmentCapable;
    import org.springframework.core.env.StandardEnvironment;
    import org.springframework.lang.Nullable;
    import org.springframework.util.Assert;
    
    /**
     * Convenient adapter for programmatic registration of annotated bean classes.
     * This is an alternative to {@link ClassPathBeanDefinitionScanner}, applying
     * the same resolution of annotations but for explicitly registered classes only.
     *
     * @author Juergen Hoeller
     * @author Chris Beams
     * @author Sam Brannen
     * @author Phillip Webb
     * @since 3.0
     * @see AnnotationConfigApplicationContext#register
     */
    public class AnnotatedBeanDefinitionReader {
    
        private final BeanDefinitionRegistry registry;
    
        private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
    
        private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
    
        private ConditionEvaluator conditionEvaluator;
    
    
        /**
         * Create a new {@code AnnotatedBeanDefinitionReader} for the given registry.
         * If the registry is {@link EnvironmentCapable}, e.g. is an {@code ApplicationContext},
         * the {@link Environment} will be inherited, otherwise a new
         * {@link StandardEnvironment} will be created and used.
         * @param registry the {@code BeanFactory} to load bean definitions into,
         * in the form of a {@code BeanDefinitionRegistry}
         * @see #AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment)
         * @see #setEnvironment(Environment)
         */
        public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
            this(registry, getOrCreateEnvironment(registry));
        }
    
        /**
         * Create a new {@code AnnotatedBeanDefinitionReader} for the given registry and using
         * the given {@link Environment}.
         * @param registry the {@code BeanFactory} to load bean definitions into,
         * in the form of a {@code BeanDefinitionRegistry}
         * @param environment the {@code Environment} to use when evaluating bean definition
         * profiles.
         * @since 3.1
         */
        public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
            Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
            Assert.notNull(environment, "Environment must not be null");
            this.registry = registry;
            this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
            // 注册通用的Annotation PostProcessor,如ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor等
            AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
        }
    
    
        /**
         * Return the BeanDefinitionRegistry that this scanner operates on.
         */
        public final BeanDefinitionRegistry getRegistry() {
            return this.registry;
        }
    
        /**
         * Set the Environment to use when evaluating whether
         * {@link Conditional @Conditional}-annotated component classes should be registered.
         * <p>The default is a {@link StandardEnvironment}.
         * @see #registerBean(Class, String, Class...)
         */
        public void setEnvironment(Environment environment) {
            this.conditionEvaluator = new ConditionEvaluator(this.registry, environment, null);
        }
    
        /**
         * Set the BeanNameGenerator to use for detected bean classes.
         * <p>The default is a {@link AnnotationBeanNameGenerator}.
         */
        public void setBeanNameGenerator(@Nullable BeanNameGenerator beanNameGenerator) {
            this.beanNameGenerator = (beanNameGenerator != null ? beanNameGenerator : new AnnotationBeanNameGenerator());
        }
    
        /**
         * Set the ScopeMetadataResolver to use for detected bean classes.
         * <p>The default is an {@link AnnotationScopeMetadataResolver}.
         */
        public void setScopeMetadataResolver(@Nullable ScopeMetadataResolver scopeMetadataResolver) {
            this.scopeMetadataResolver =
                    (scopeMetadataResolver != null ? scopeMetadataResolver : new AnnotationScopeMetadataResolver());
        }
    
    
        /**
         * Register one or more annotated classes to be processed.
         * <p>Calls to {@code register} are idempotent; adding the same
         * annotated class more than once has no additional effect.
         * @param annotatedClasses one or more annotated classes,
         * e.g. {@link Configuration @Configuration} classes
         */
        public void register(Class<?>... annotatedClasses) {
            for (Class<?> annotatedClass : annotatedClasses) {
                registerBean(annotatedClass);
            }
        }
    
        /**
         * Register a bean from the given bean class, deriving its metadata from
         * class-declared annotations.
         * @param annotatedClass the class of the bean
         */
        public void registerBean(Class<?> annotatedClass) {
            doRegisterBean(annotatedClass, null, null, null);
        }
    
        /**
         * Register a bean from the given bean class, deriving its metadata from
         * class-declared annotations, using the given supplier for obtaining a new
         * instance (possibly declared as a lambda expression or method reference).
         * @param annotatedClass the class of the bean
         * @param instanceSupplier a callback for creating an instance of the bean
         * (may be {@code null})
         * @since 5.0
         */
        public <T> void registerBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier) {
            doRegisterBean(annotatedClass, instanceSupplier, null, null);
        }
    
        /**
         * Register a bean from the given bean class, deriving its metadata from
         * class-declared annotations, using the given supplier for obtaining a new
         * instance (possibly declared as a lambda expression or method reference).
         * @param annotatedClass the class of the bean
         * @param name an explicit name for the bean
         * @param instanceSupplier a callback for creating an instance of the bean
         * (may be {@code null})
         * @since 5.0
         */
        public <T> void registerBean(Class<T> annotatedClass, String name, @Nullable Supplier<T> instanceSupplier) {
            doRegisterBean(annotatedClass, instanceSupplier, name, null);
        }
    
        /**
         * Register a bean from the given bean class, deriving its metadata from
         * class-declared annotations.
         * @param annotatedClass the class of the bean
         * @param qualifiers specific qualifier annotations to consider,
         * in addition to qualifiers at the bean class level
         */
        @SuppressWarnings("unchecked")
        public void registerBean(Class<?> annotatedClass, Class<? extends Annotation>... qualifiers) {
            doRegisterBean(annotatedClass, null, null, qualifiers);
        }
    
        /**
         * Register a bean from the given bean class, deriving its metadata from
         * class-declared annotations.
         * @param annotatedClass the class of the bean
         * @param name an explicit name for the bean
         * @param qualifiers specific qualifier annotations to consider,
         * in addition to qualifiers at the bean class level
         */
        @SuppressWarnings("unchecked")
        public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
            doRegisterBean(annotatedClass, null, name, qualifiers);
        }
    
        /**
         *
         * 根据给定bean的Class,将该beanDefinition注册到容器中
         *
         * Register a bean from the given bean class, deriving its metadata from
         * class-declared annotations.
         * @param annotatedClass the class of the bean
         * @param instanceSupplier a callback for creating an instance of the bean
         * (may be {@code null})
         * @param name an explicit name for the bean
         * @param qualifiers specific qualifier annotations to consider, if any,
         * in addition to qualifiers at the bean class level
         * @param definitionCustomizers one or more callbacks for customizing the
         * factory's {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
         * @since 5.0
         */
        <T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
                @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
            // AnnotatedGenericBeanDefinition,能够获取该Class上所有的注解元数据
            AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
            // @Conditional条件判断
            if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
                return;
            }
    
            abd.setInstanceSupplier(instanceSupplier);
            // 解析并设置bean的scope信息
            ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
            abd.setScope(scopeMetadata.getScopeName());
            String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
    
            // 解析@Lazy @DependsOn @Description @Primary等注解,并在beanDefinition中设置对应的值
            AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
            if (qualifiers != null) {
                for (Class<? extends Annotation> qualifier : qualifiers) {
                    if (Primary.class == qualifier) {
                        abd.setPrimary(true);
                    }
                    else if (Lazy.class == qualifier) {
                        abd.setLazyInit(true);
                    }
                    else {
                        abd.addQualifier(new AutowireCandidateQualifier(qualifier));
                    }
                }
            }
            for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
                customizer.customize(abd);
            }
    
            // 包装成BeanDefinitionHolder
            BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
            // 代理模式 NO、JDK(接口)、CGLIB(普通类)
            definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
            // 注册beanDefinition
            BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
        }
    
    
        /**
         * Get the Environment from the given registry if possible, otherwise return a new
         * StandardEnvironment.
         */
        private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
            Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
            if (registry instanceof EnvironmentCapable) {
                return ((EnvironmentCapable) registry).getEnvironment();
            }
            return new StandardEnvironment();
        }
    
    }
    
    

    调用AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) 构造方法,会最终调用AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) 方法。

        /**
         * Create a new {@code AnnotatedBeanDefinitionReader} for the given registry and using
         * the given {@link Environment}.
         * @param registry the {@code BeanFactory} to load bean definitions into,
         * in the form of a {@code BeanDefinitionRegistry}
         * @param environment the {@code Environment} to use when evaluating bean definition
         * profiles.
         * @since 3.1
         */
        public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
            Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
            Assert.notNull(environment, "Environment must not be null");
            this.registry = registry;
            this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
            // 向容器注册 post processor
            AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
        }
    

    这里会初始化conditionEvaluator(用于@Conditional注解的处理)以及向容器注册相关的注解配置相关的“后置处理器”(post processor)。

    AnnotationConfigUtils的registerAnnotationConfigProcessors(BeanDefinitionRegistry registry)方法会最终调用其registerAnnotationConfigProcessors(
    BeanDefinitionRegistry registry, @Nullable Object source)方法。

    不多说,直接上代码

        /**
         * Register all relevant annotation post processors in the given registry.
         * @param registry the registry to operate on
         * @param source the configuration source element (already extracted)
         * that this registration was triggered from. May be {@code null}.
         * @return a Set of BeanDefinitionHolders, containing all bean definitions
         * that have actually been registered by this call
         */
        public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
                BeanDefinitionRegistry registry, @Nullable Object source) {
    
            // 从bean definition registry中获得DefaultListableBeanFactory
            DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
            if (beanFactory != null) {
                // 设置beanFactory的 dependency comparator(排序相关)
                if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
                    beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
                }
                // 设置autowireCandidateResolver(自动装配相关)
                if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
                    beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
                }
            }
    
            Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
            // 不存在就注册ConfigurationClassPostProcessor的bean definition,该ConfigurationClassPostProcessor是一个BeanFactoryPostProcessor,用于处理@Configuration相关注解
            if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
            }
    
            // 不存在就注册AutowiredAnnotationBeanPostProcessor,该post processor是一个BeanPostProcessor,用于@Autowired注解的处理
            if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
            }
    
            // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
            // 不存在就注册CommonAnnotationBeanPostProcessor,用于处理JSR-250规范定义的相关注解
            if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
            }
    
            // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
            // 有JPA相关的类存在的话,就注册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));
            }
           // 事件相关的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));
            }
            // event listener factoryBean的注册
            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));
            }
    
            return beanDefs;
        }
    

    至此,AnnotationConfigApplicationContext的初始化过程大体结束。

    回顾AnnotationConfigApplicationContext的初始化过程,最核心的其实也就是在AnnotationConfigUtils的registerAnnotationConfigProcessors方法上。BeanPostProcessor以及BeanFactoryPostProcessor是spring非常重要的两大扩展点,AnnotationConfigApplicationContext初始化时,注册了很多默认的post processor的bean definition。

    register方法注册配置类流程分析

    TODO ...

    相关文章

      网友评论

          本文标题:Spring IOC容器之AnnotationConfigApp

          本文链接:https://www.haomeiwen.com/subject/ieqdnctx.html