zoukankan      html  css  js  c++  java
  • 2.2 spring5源码 -- ioc加载的整体流程

    之前我们知道了spring ioc的加载过程, 具体如下图. 下面我们就来对照下图, 看看ioc加载的源代码.

     下面在用装修类比, 看看个个组件都是怎么工作的.

    接下来是源码分析的整体结构图. 对照上面的思路梳理出来的

    一、源码分析的入口 

    通常,我们的入口都是从main方法进入. 这里我们也来定义一个main方法

    public class MainStarter {
        public static void main(String[] args) {
            // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainStarter.class);
            context.scan("package name");
            Car car = (Car) context.getBean("car");
            System.out.println(car.getName());
            context.close();
        }
    }

    顺便再来看看还有哪些相关的类

    /**
     * 这是一个配置类,
     * 在配置类里面定义了扫描的包路径com.lxl.www.iocbeanlifecicle
     * 这是会将这个包下配置了注解的类扫描到ioc容器里面,成为一个成熟的bean
     */
    @Configuration
    @ComponentScan(basePackages = {"com.lxl.www.iocbeanlifecicle"})
    public class MainConfig {
    }

    这个类有一个注解@Configuration, 这样这个类会被扫描成bean

    还有一个注解@ComponentScan(backPackage = {"com.lxl.www.iocbeanlifecicle"}) 他表示, 请扫描com.lxl.www.iocbeanlifecicle包下所有的类.

    com.lxl.www.iocbeanlifecicle 这个包下还有哪些类呢? 我们来看看项目结构

     这是这个包下完整的项目结构. 

    下面会逐渐说明, 每个类的用途

    二. 最重要的类BeanFactory

    我们知道在将一个class加载为bean的过程中BeanFactory是最最重要的, 那么他是何时被加载的呢?

    我们来跟踪一下带有一个参数的构造方法AnnotationConfigApplicationContext

        public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
            // 进入构造函数, 首先调用自身的构造方法this();
            // 调用自身的构造方法之前, 要先调用父类的构造方法
            this();
            // retister配置注册类
            register(componentClasses);
            // ioc容器shua新接口--非常重要
            refresh();
        }

    这就是AnnotationConfigApplicationContext初始化的时候做的三件事

    第一件事:  this();  //调用自身的无参构造方法. 同时调用父类的构造方法

    第二件事: register(componentClasses); // 调用注册器, 这里会加载两个BeanDefinitionReader和BeanDefinitionScanner. 这两位的角色是什么呢? 可以回忆一下之前的框架图

    第三件事: refresh();  // 这是ioc容器刷新, 非常重要. 无论是spring boot还是spring mvc都有这个方法. 这个方法包含了整个spring ioc加载的全生命流程. 也是我们要重点学习的方法

    下面来看看BeanFactory是何时被加载进来的呢?

    在初始化方法的时候调用了自身的无参构造函数, 在调用自身无参构造函数的时候, 同时会调用父类的无参构造函数. 

    public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
      ......
    }

    父类是GenericApplicationContext, 其无参构造函数就做了一件事

       public GenericApplicationContext() {
            // 构造了一个BeanFactory.
            // 在调用GenericApplicationContext父类构造函数, 为ApplicationContext spring上下文对象初始化beanFactory
            // 为什么初始化的是DefaultListableBeanFactory呢?
            // 我们在看BeanFactory接口的时候发现DefaultListableBeanFactory是最底层的实现, 功能是最全的.
            // 查看
            this.beanFactory = new DefaultListableBeanFactory();
        }    

    初始化DefaultListableBeanFactory. 

    问题: BeanFactory有很多, 为什么初始化的时候选择DefaultListableBeanFactory呢?

    我们来看看DefaultListableBeanFactory的结构. 快捷键option + command + u --> Java Class Diagrams

     通过观察, 我们发现, DefaultListableBeanFactory实现了各种各样的BeanFactory接口, 同时还是先了BeanDefinitionRegistry接口. 

    也就是说, DefaultListableBeanFactory不仅仅有BeanFactory的能力, 同时还有BeanDefinitionRegistry的能力. 它的功能是最全的.

    所以, 我们使用的是一个功能非常强大的类Bean工厂类. 

    AnnotationConfigApplicationContext继承了GenericApplicationContext,

    而 GenericApplicationContext 实现了AnnotationConfigRegistry接口.

    所以AnnotationConfigApplicationContext有AnnotationConfigRegistry的能力.

    三. bean定义读取器AnnotatedBeanDefinitionReader

    接着上面, 第一步调用的是this(). 也就是AnnotationConfigApplicationContext的无参构造函数. 在这个无参构造函数里一共做了两件事情

        public AnnotationConfigApplicationContext() {
            /**
             * 创建了一个Bean定义的读取器.
             * 完成了spring内部BeanDefinition的注册(主要是后置处理器)
             * 读取了很多spring自定义的配置(主要是后置处理器). 这些类都是spring 的原始类.
             */
            this.reader = new AnnotatedBeanDefinitionReader(this);
    
            /**
             * 创建BeanDefinition扫描器
             * 可以用来扫描包或者类, 进而转换为bd
             *
             * Spring默认的扫描包不是这个scanner对象
             * 而是自己new的一个ClassPathBeanDefinitionScanner
             * Spring在执行工程后置处理器ConfigurationClassPostProcessor时, 去扫描包时会new一个ClassPathBeanDefinitionScanner
             *
             * 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法
             * 通过调用context.scan("package name");扫描处理配置类
             * 扫描
             */
            this.scanner = new ClassPathBeanDefinitionScanner(this);
        }

    1. 初始化AnnotatedBeanDefinitionReader.

    2. 初始化ClassPathBeanDefinitionScanner

    我们先来看看AnnotatedBeanDefinitionReader

     在这里的描述中, 我们知道BeanDefinitionReader是要去扫描配置或者注解, 如果理解为销售的话, 就是扫描楼盘. 这里面就有我们的潜在用户. 也就是我们需要将其转换为bean的对象. 

    那么初始化的时候,AnnotatedBeanDefinitionReader做了什么呢?

    重点看这句

        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);
         // 注册注解类型配置的处理器 AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); }

    注册注解类型配置的处理器

    AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);

       /**
         * 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) {
    
            // 获取到beanFactory
            DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
            /**
             * 判断beanFactory中是否有AnnotationAwareOrderComparator和ContextAnnotationAutowireCandidateResolver
             * 没有则添加
             */
            if (beanFactory != null) {
                if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
                    beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
                }
                if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
                    beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
                }
            }
    
            // BeanDefinitionHolder: 为BeanDefinition设置名字和别名
            Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
    
            // 1. 如果registry中没有ConfigurationClassPostProcessor配置类后置处理器, 就添加一个
            if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
                def.setSource(source);
                // 构建BeanDefinitionHolder, 并添加到beanDefs
                beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
            }
    
            // 2. 如果rigistry中, 没有AutowiredAnnotationBeanPostProcessor  Autowired注解bean的后置处理器, 则添加一个
            if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
                def.setSource(source);
                // 构建BeanDefinitionHolder, 并添加到beanDefs
                beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
            }
    
            // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
            // 3. 检查对JSR-250的支持, 如果rigistry中没有CommonAnnotationBeanPostProcessor通用注解后置处理器, 则添加一个
            if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
                def.setSource(source);
                // 构建BeanDefinitionHolder, 并添加到beanDefs
                beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
            }
    
            // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
            // 4. 检查对jpa的支持, 如果不包含internalPersistenceAnnotationProcessor, 持久化注解处理器, 就添加一个
            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));
            }
    
            // 5. 检查对事件监听的支持, 如果不包含事件监听处理器internalEventListenerProcessor, 就添加一个
            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));
            }
    
            // 6. 如果不包含事件监听工厂处理器internalEventListenerFactory , 就添加一个
            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;
        }

    在这里注册了6个后置处理器.

     

    四. bean定义扫描器ClassPathBeanDefinitionScanner

      public AnnotationConfigApplicationContext() {
            /**
             * 创建了一个Bean定义的读取器.
             * 完成了spring内部BeanDefinition的注册(主要是后置处理器)
             * 读取了很多spring自定义的配置(主要是后置处理器). 这些类都是spring 的原始类.
             */
            this.reader = new AnnotatedBeanDefinitionReader(this);
    
            /**
             * 创建BeanDefinition扫描器
             * 可以用来扫描包或者类, 进而转换为bd
             *
             * Spring默认的扫描包不是这个scanner对象
             * 而是自己new的一个ClassPathBeanDefinitionScanner
             * Spring在执行工程后置处理器ConfigurationClassPostProcessor时, 去扫描包时会new一个ClassPathBeanDefinitionScanner
             *
             * 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法
             * 通过调用context.scan("package name");扫描处理配置类
             * 扫描
             */
            this.scanner = new ClassPathBeanDefinitionScanner(this);
        }

    主要看加粗的部分. 这部分初始化了BeanDefinition扫描器. 这里的这个scanner不是spring默认的扫描包. Spring默认的扫描包不是这个scanner对象, 而是自己new的一个ClassPathBeanDefinitionScanner, Spring在执行后置处理器ConfigurationClassPostProcessor时, 去扫描包时会new一个ClassPathBeanDefinitionScanner, 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法, 通过调用context.scan("package name");扫描处理配置类

     比如,我们可以这样使用

        public static void main(String[] args) {
            // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainStarter.class);
            context.scan("package name");
            Car car = (Car) context.getBean("car");
            System.out.println(car.getName());
            context.close();
        }

    首先调用了ClassPathBeanDefinitionScanner(this) 构造方法, 然后调用registerDefaultFilter注册摩尔恩的过滤器, 这里面默认的过滤器有两种: javax.annotation.ManagedBean 和 javax.inject.Named. 同时隐含的会注册所有带有@Component @Repository @Controller关键字的注解

        @SuppressWarnings("unchecked")
        protected void registerDefaultFilters() {
            this.includeFilters.add(new AnnotationTypeFilter(Component.class));
            ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
            try {
                this.includeFilters.add(new AnnotationTypeFilter(
                        ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
                logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
            }
            catch (ClassNotFoundException ex) {
                // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
            }
            try {
                this.includeFilters.add(new AnnotationTypeFilter(
                        ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
                logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
            }
            catch (ClassNotFoundException ex) {
                // JSR-330 API not available - simply skip.
            }
        }

    在ClassPathBeanDefinitionScanner中, 有一个非常重要的方法, 就是doScan(String ....beanPackages). 用来扫描传入的配置文件.

    五.  注册配置方法

        public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
            // 进入构造函数, 首先调用自身的构造方法this();
            // 调用自身的构造方法之前, 要先调用父类的构造方法
            this();
            // register配置注册类
            register(componentClasses);
            // ioc容器shua新接口--非常重要
            refresh();
        }

    这是AnnotationConfigApplicationContext方法的构造函数, 里面第二步调用了register()方法. 

     

      private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
                @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
                @Nullable BeanDefinitionCustomizer[] customizers) {
    
            // 将入参beanClass构建成AnnotatedGenericBeanDefinition对象
            AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
            if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
                return;
            }
    
            abd.setInstanceSupplier(supplier);
            ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
            abd.setScope(scopeMetadata.getScopeName());
            String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
    
            // 处理通用定义注解
            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));
                    }
                }
            }
            if (customizers != null) {
                for (BeanDefinitionCustomizer customizer : customizers) {
                    customizer.customize(abd);
                }
            }
    
            BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
            definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
            BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
        }

    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);用来加载bean元数据中的注解

    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);用来注册bean定义. 经过一些列的教研, 没有问题, 然后将其让入到this.beanDefinitionMap.put(beanName, beanDefinition);中
    具体做了哪些工作, 可以看看上面的结构图

     六. Refresh() -- spring ioc容器刷新方法

        public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
            // 进入构造函数, 首先调用自身的构造方法this();
            // 调用自身的构造方法之前, 要先调用父类的构造方法
            this();
            // register配置注册类
            register(componentClasses);
            // ioc容器shua新接口--非常重要
            refresh();
        }

    refresh()方法, spring有很多衍生品, 比如spring mvc ,spring boot, 都有这个方法. refresh()里面定义了spring ioc中bean加载的全过程. 

        @Override
        public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
                // 1. 准备刷新上下文环境
                prepareRefresh();
    
                // Tell the subclass to refresh the internal bean factory.
                //2. 获取告诉子类初始化bean工厂, 不同工厂不同实现
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
    
                // Prepare the bean factory for use in this context.
                //3. 对bean工厂进行填充属性
                prepareBeanFactory(beanFactory);
    
                try {
                    // Allows post-processing of the bean factory in context subclasses.
                    // 4. 留个子类去实现该接口
                    postProcessBeanFactory(beanFactory);
    
                    // Invoke factory processors registered as beans in the context.
                    /*
                     * 调用bean工厂的后置处理器
                     * 1. 会再次class扫描成BeanDefinition
                     */
                    invokeBeanFactoryPostProcessors(beanFactory);
    
                    // Register bean processors that intercept bean creation.
                    // 注册bean后置处理器
                    registerBeanPostProcessors(beanFactory);
    
                    // Initialize message source for this context.
                    // 初始化国际化资源处理器
                    initMessageSource();
    
                    // Initialize event multicaster for this context.
                    // 创建事件多播放器
                    initApplicationEventMulticaster();
    
                    // Initialize other special beans in specific context subclasses.
                    // 这个方法通用也是留个子类实现的, spring boot也是从这个方法进行启动
                    onRefresh();
    
                    // Check for listener beans and register them.
                    // 将事件监听器注册到多播放器上
                    registerListeners();
    
                    // Instantiate all remaining (non-lazy-init) singletons.
                    // 实例化剩余的单实例bean
                    /**
                     * 这个方法就是循环遍历BeanDefinitionMap, 调用getBean, 去生产bean
                     */
                    finishBeanFactoryInitialization(beanFactory);
    
                    // Last step: publish corresponding event.
                    //最后容器刷新 发布刷新时间(spring cloud是从这里启动的 )
                    finishRefresh();
                }
    
                catch (BeansException ex) {
                    if (logger.isWarnEnabled()) {
                        logger.warn("Exception encountered during context initialization - " +
                                "cancelling refresh attempt: " + ex);
                    }
    
                    // Destroy already created singletons to avoid dangling resources.
                    destroyBeans();
    
                    // Reset 'active' flag.
                    cancelRefresh(ex);
    
                    // Propagate exception to caller.
                    throw ex;
                }
    
                finally {
                    // Reset common introspection caches in Spring's core, since we
                    // might not ever need metadata for singleton beans anymore...
                    resetCommonCaches();
                }
            }
        }

    这是refresh()的源码, 在refresh()中做了很多很多事情, 我们这次主要看和ioc中beanFactory创建bean有关的部分.

    一个是: invokeBeanFactoryPostProcessors(beanFactory);

    另一个是: finishBeanFactoryInitialization(beanFactory);

    6.1 invokeBeanFactoryPostProcessors(beanFactory) 调用BeanFactory的后置处理器

     在AnnotatedBeanDefinitionReader这里扫描了所有后置处理器, 将其解析到beanDefinitionMap, 在这里调用后置处理器

    6.2 finishBeanFactoryInitialization 实例化剩余的单实例bean

     这个方法就是循环遍历BeanDefinitionMap, 调用getBean, 去生产bean

    这里第一个是: 冻结配置类, 意思是说, 我马上就要开始制造bean了, bean配置文件不能再修改了, 所以被冻结

    原理是有一个变量标记, 设为true标记冻结.

        @Override
        public void freezeConfiguration() {
            this.configurationFrozen = true;
            this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
        }

    第二个是实例化创建bean

    Override
        protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                throws BeanCreationException {
    
            if (logger.isTraceEnabled()) {
                logger.trace("Creating instance of bean '" + beanName + "'");
            }
            RootBeanDefinition mbdToUse = mbd;
    
            // Make sure bean class is actually resolved at this point, and
            // clone the bean definition in case of a dynamically resolved Class
            // which cannot be stored in the shared merged bean definition.
            // 确保此时的bean已经被解析了
            Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
            if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
                mbdToUse = new RootBeanDefinition(mbd);
                mbdToUse.setBeanClass(resolvedClass);
            }
    
            // Prepare method overrides.
            try {
                /**
                 * 验证和准备覆盖方法(近在xml方式中)
                 * lookup-method 和 replace-method
                 * 这两个配置存放在BeanDefinition中的methodOverrides(仅在XML方式中)
                 * 在XML方式中, bean实例化的过程中如果检测到存在methodOverrides
                 * 则会动态的为当前bean生成代理并使用对应的拦截器为bean做增强处理
                 * 具体的实现我们后续分析. 现在先看mbdtoUse.prepareMethodOverrides()代码块
                 */
                mbdToUse.prepareMethodOverrides();
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                        beanName, "Validation of method overrides failed", ex);
            }
    
            try {
                // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
                /**
                 * 初始化之前的解析
                 * 第一次调用bean后置处理器
                 * 铜鼓bean的后置处理器来进行后置处理生成代理对象, 一般情况下在此处不会生成代理对象
                 * 为什么不能生成代理对象? 不管是我们的JDK还是cglib代理都不会在此处进行代理, 因为我们的真实对象没有生成,
                 * 所以在这里不会生成代理对象
                 * 这一步是aop和事务的关键, 因为在这解析我们的aop切面信息进行缓存.
                 */
                Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
                if (bean != null) {
                    return bean;
                }
            }
            catch (Throwable ex) {
                throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                        "BeanPostProcessor before instantiation of bean failed", ex);
            }
    
            try {
                /*
                 * 执行创建bean, 这里就是执行创建bean的三个步骤
                 * 1. 实例化
                 * 2. 填充属性, @Autowired @Value
                 * 3. 初始化  初始化initMethod方法和初始化destroy方法
                 */
                Object beanInstance = doCreateBean(beanName, mbdToUse, args);
                if (logger.isTraceEnabled()) {
                    logger.trace("Finished creating instance of bean '" + beanName + "'");
                }
                return beanInstance;
            }
            catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
                // A previously detected exception with proper bean creation context already,
                // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
                throw ex;
            }
            catch (Throwable ex) {
                throw new BeanCreationException(
                        mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
            }
        }

    创建bean的三个步骤 

    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
                throws BeanCreationException {
    
            // Instantiate the bean.
            BeanWrapper instanceWrapper = null;
            if (mbd.isSingleton()) {
                instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
            }
            if (instanceWrapper == null) {
                /**
                 * 第一步: 实例化
                 * 这里面的调用链非常深, 后面再看
                 * bean实例化有两种方式
                 * 1. 使用反射:  使用反射也有两种方式,
                 *         a. 通过无参构造函数 (默认的方式)
                 *             从beanDefinition中可以得到beanClass,
                 *             ClassName = BeanDefinition.beanclass
                 *             Class clazz = Class.forName(ClassName);
                 *             clazz.newInstance();
                 *             这样就可以实例化bean了
                 *
                 *         b. 通过有参函数.
                 *            ClassName = BeanDefinition.beanclass
                 *             Class clazz = Class.forName(ClassName);
                 *             Constractor con = class.getConstractor(args....)
                 *             con.newInstance();
                 *
                 * 2. 使用工厂
                 *         我们使用@Bean的方式, 就是使用的工厂模式, 自己控制实例化过程
                 *
                 */
                instanceWrapper = createBeanInstance(beanName, mbd, args);
            }
            // 这里使用了装饰器的设计模式
            final Object bean = instanceWrapper.getWrappedInstance();
            Class<?> beanType = instanceWrapper.getWrappedClass();
            if (beanType != NullBean.class) {
                mbd.resolvedTargetType = beanType;
            }
    
            // Allow post-processors to modify the merged bean definition.
            // 允许后置处理器修改已经合并的beanDefinition
            synchronized (mbd.postProcessingLock) {
                if (!mbd.postProcessed) {
                    try {
                        applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                    }
                    catch (Throwable ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Post-processing of merged bean definition failed", ex);
                    }
                    mbd.postProcessed = true;
                }
            }
    
            // Eagerly cache singletons to be able to resolve circular references
            // even when triggered by lifecycle interfaces like BeanFactoryAware.
            boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                    isSingletonCurrentlyInCreation(beanName));
            if (earlySingletonExposure) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Eagerly caching bean '" + beanName +
                            "' to allow for resolving potential circular references");
                }
                addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
            }
    
            // Initialize the bean instance.
            Object exposedObject = bean;
            try {
                // 第二步:填充属性, 给属性赋值(调用set方法)  这里也是调用的后置处理器
                populateBean(beanName, mbd, instanceWrapper);
                // 第三步: 初始化.
                exposedObject = initializeBean(beanName, exposedObject, mbd);
            }
            catch (Throwable ex) {
                if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
                    throw (BeanCreationException) ex;
                }
                else {
                    throw new BeanCreationException(
                            mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
                }
            }
    
            if (earlySingletonExposure) {
                Object earlySingletonReference = getSingleton(beanName, false);
                if (earlySingletonReference != null) {
                    if (exposedObject == bean) {
                        exposedObject = earlySingletonReference;
                    }
                    else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                        String[] dependentBeans = getDependentBeans(beanName);
                        Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                        for (String dependentBean : dependentBeans) {
                            if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                                actualDependentBeans.add(dependentBean);
                            }
                        }
                        if (!actualDependentBeans.isEmpty()) {
                            throw new BeanCurrentlyInCreationException(beanName,
                                    "Bean with name '" + beanName + "' has been injected into other beans [" +
                                    StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                    "] in its raw version as part of a circular reference, but has eventually been " +
                                    "wrapped. This means that said other beans do not use the final version of the " +
                                    "bean. This is often the result of over-eager type matching - consider using " +
                                    "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                        }
                    }
                }
            }
    
            // Register bean as disposable.
            try {
                registerDisposableBeanIfNecessary(beanName, bean, mbd);
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
            }
    
            return exposedObject;
        }

    具体结构如下:

    我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1gx5pavn3x1pz

  • 相关阅读:
    慕课网-安卓工程师初养成-2-6 Java中的数据类型
    慕课网-安卓工程师初养成-2-5 如何命名Java变量
    慕课网-安卓工程师初养成-2-4 变量是什么
    慕课网-安卓工程师初养成-2-3 练习题
    慕课网-安卓工程师初养成-2-2 认识Java标识符
    慕课网-安卓工程师初养成-2-1 Java中的关键字
    慕课网-安卓工程师初养成-1-10 练习题
    Java编程——万年历
    排队购票
    猴子爬山
  • 原文地址:https://www.cnblogs.com/ITPower/p/13723084.html
Copyright © 2011-2022 走看看