zoukankan      html  css  js  c++  java
  • (3)spring源码解析-refresh()方法之前

    本文是作者原创,版权归作者所有.若要转载,请注明出处.

    本文源码版本5.1.x.话不多说,开始

    首先是配置类

    @Configuration
    @ComponentScan("com.day01")
    public class SpringConfig {
    
    }

    IndexService

    @Service
    public class IndexService  {
        
        public IndexService(){
            System.out.println("IndexService  构造方法");
        }
    
        @PostConstruct
        public void init(){
            System.out.println("IndexService  init方法");
        }
    
    
        public void hello(){
            System.out.println("IndexService  hello");
        }
    }

    测试类

    public static void main(String[] args) {
            AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfig.class);
            //AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(IndexService.class);
            IndexService indexService = (IndexService) applicationContext.getBean("indexService");
            indexService.hello();
            System.out.println(indexService);
        }

    第一行点进去

    public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
            //annotatedClasses --->  配置类的class对象
            this();
            register(annotatedClasses);
            refresh();
        }

    今天我们先看refresh()方法之前的源码

    this()调的构造器如下

    public AnnotationConfigApplicationContext() {
            /**
             * 父类的构造方法
             * 创建一个读取注解的Bean定义读取器
             * 什么是BeanDefinition
             */
            super();
            this.reader = new AnnotatedBeanDefinitionReader(this);
            //可以用来扫描包或者类,继而转换成BeanDefinition
            //但是实际上我们扫描包工作不是scanner这个对象来完成的
            //是spring自己new的一个ClassPathBeanDefinitionScanner
            //这里的scanner仅仅是为了程序员能够在外部调用AnnotationConfigApplicationContext对象的scan方法
            this.scanner = new ClassPathBeanDefinitionScanner(this);
        }
    /**
         * 这个类顾名思义是一个reader,一个读取器
         * 读取什么呢?还是顾名思义:AnnotatedBeanDefinition意思是读取一个被加了注解的BeanDefinition
         * 这个类在构造方法中实例化的
         */
        private final AnnotatedBeanDefinitionReader reader;
    
        /**
         * 同意顾名思义,这是一个扫描器,扫描所有加了注解的bean
         *  同样是在构造方法中被实例化的
         */
        private final ClassPathBeanDefinitionScanner scanner;

    先看super()父类构造器

    public GenericApplicationContext() {
            this.beanFactory = new DefaultListableBeanFactory();
        }

    可以看出初始化beanFactory 为默认实现DefaultListableBeanFactory

    我们看一下些DefaultListableBeanFactory的属性和方法

    
    
    public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
    implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {

    /**
    Map of bean definition objects, keyed by bean name. */ private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256); /** List of bean definition names, in registration order. */ private volatile List<String> beanDefinitionNames = new ArrayList<>(256); //手动注册的单例对象的名称列表,按注册顺序排列 /** List of names of manually registered singletons, in registration order. */ private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);

    @Override
    public <T> T getBean(Class<T> requiredType) throws BeansException {
    return getBean(requiredType, (Object[]) null);
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException {
    Assert.notNull(requiredType, "Required type must not be null");
    Object resolved = resolveBean(ResolvableType.forRawClass(requiredType), args, false);
    if (resolved == null) {
    throw new NoSuchBeanDefinitionException(requiredType);
    }
    return (T) resolved;
    }
    }

    可以看出,这是bean工厂的实现类,里面有存BeanDefinition和beanDefinitionNames 的map和getBean等方法

    父类构造器结束,就是实例了一个默认的bean工厂,继续下一行

    this.reader = new AnnotatedBeanDefinitionReader(this);

    点进去看源码

    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
            this(registry, getOrCreateEnvironment(registry));
        }

    这里BeanDefinitionRegistry是一个BeanDefinition注册器

    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);
        }

    继续看最后一行

    public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
            registerAnnotationConfigProcessors(registry, null);
        }

    继续跟进去

    public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
    BeanDefinitionRegistry registry, @Nullable Object source) {

    DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
    if (beanFactory != null) {
    if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
    beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);//AnnotationAwareOrderComparator主要能解析@Order注解和@Priority
    }
    if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
    beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());//ContextAnnotationAutowireCandidateResolver提供处理延迟加载的功能
    }
    }

    //a Set of BeanDefinitionHolders, containing all bean definitions
    //BeanDefinitionHolder是存储BeanDefinitionName和BeanDefinition的一个数据结构
    Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
    //BeanDefinitio的注册,这里很重要,需要理解注册每个bean的类型,CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME=internalConfigurationAnnotationProcessor
    if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
    //ConfigurationClassPostProcessor是一个BeanFactory的后置处理器,主要功能是解析加了@Configuration的配置类,还会解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解
    //需要注意的是ConfigurationClassPostProcessor的类型是BeanDefinitionRegistryPostProcessor
    //而 BeanDefinitionRegistryPostProcessor 最终实现BeanFactoryPostProcessor这个接口
    RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
    def.setSource(source);
    beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    //AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME=internalAutowiredAnnotationProcessor
    if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
    //AutowiredAnnotationBeanPostProcessor是解析AutoWired注解的BeanPostProcessor
    //AutowiredAnnotationBeanPostProcessor 实现了 MergedBeanDefinitionPostProcessor
    //MergedBeanDefinitionPostProcessor 最终实现了 BeanPostProcessor
    RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
    def.setSource(source);
    beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    //COMMON_ANNOTATION_PROCESSOR_BEAN_NAME=internalCommonAnnotationProcessor
    // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
    if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
    //CommonAnnotationBeanPostProcessor支持对@PostConstruct和@PreDestroy注解,以及对@Resource注解的处理
    RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
    def.setSource(source);
    beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
    //PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME=internalPersistenceAnnotationProcessor,跳过,不重要
    // Check for JPA support, and if present add the 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));
    }
    //EVENT_LISTENER_PROCESSOR_BEAN_NAME=internalEventListenerProcessor
    if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
    //EventListenerMethodProcessor支持事件监听,不太熟
    RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
    def.setSource(source);
    beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
    }
    //EVENT_LISTENER_FACTORY_BEAN_NAME=internalEventListenerFactory
    if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
    //DefaultEventListenerFactory不太了解,事件监听相关
    RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
    def.setSource(source);
    beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
    }

    return beanDefs;
    }

    这里的BeanDefinitionHolder看下

    public class BeanDefinitionHolder implements BeanMetadataElement {
    
        private final BeanDefinition beanDefinition;
    
        private final String beanName;
    
        @Nullable
        private final String[] aliases;
      //省略 }

    可以认为:BeanDefinitionHolder是存储BeanDefinitionName和BeanDefinition的一个数据结构

    debug看下最后一行的结果

     可以看出,bean工厂已经存在5个BeanDefinition,我们继续看下面的源码

    读取器看完了,扫描器先不看了,我们看register(annotatedClasses);方法

    public void register(Class<?>... annotatedClasses) {
            Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
            this.reader.register(annotatedClasses);//被注解的类
        }

    继续跟下去

    public void register(Class<?>... annotatedClasses) {
            for (Class<?> annotatedClass : annotatedClasses) {
                registerBean(annotatedClass);
            }
        }

    这里循环处理所有要处理的annotated类。如:Configuration注解的配置类

    public void registerBean(Class<?> annotatedClass) {
            doRegisterBean(annotatedClass, null, null, null);
        }

    继续跟

    <T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
                @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
    
            /**
             * 根据指定的bean创建一个AnnotatedGenericBeanDefinition
             * 这个AnnotatedGenericBeanDefinition可以理解为一个数据结构
             * AnnotatedGenericBeanDefinition包含了类的其他信息,比如一些元信息
             * scope,lazy等等.
             * 此时因为传入的注解,所以new AnnotatedGenericBeanDefinition
             */
            AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
            /**
             * 判断这个类是否需要跳过解析
             * 通过代码可以知道spring判断是否跳过解析,主要判断类有没有加注解
             */
            if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
                return;
            }
    
            abd.setInstanceSupplier(instanceSupplier);
            /**
             * 得到类的作用域 singleton
             */
            ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
            /**
             * 把类的作用域添加到数据结构结构中
             */
            abd.setScope(scopeMetadata.getScopeName());
            /**
             * 生成类的名字通过beanNameGenerator
             */
            String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
            /**
             * 处理类当中的通用注解
             * 分析源码可以知道他主要处理
             * Lazy DependsOn Primary Role等等注解
             * 处理完成之后processCommonDefinitionAnnotations中依然是把他添加到AnnotatedGenericBeanDefinition数据结构当中
             */
            AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
            if (qualifiers != null) {//qualifiers总是为null
                for (Class<? extends Annotation> qualifier : qualifiers) {
                    //如果配置了@Primary注解,如果加了则作为首选
                    if (Primary.class == qualifier) {
                        abd.setPrimary(true);
                    }
                    //懒加载注解
                    else if (Lazy.class == qualifier) {
                        abd.setLazyInit(true);
                    }
                    else {
                        //如果使用了除@Primary和@Lazy以外的其他注解,则为该Bean添加一个根据名字自动装配的限定符
                        //这里难以理解,后面会详细介绍
                        abd.addQualifier(new AutowireCandidateQualifier(qualifier));
                    }
                }
            }
            //自定义注解
            for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
                customizer.customize(abd);
            }
    
            /**
             * 这个BeanDefinitionHolder也是一个数据结构,这个对象放入了BeanDefinition和beanName
             */
            BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
            /**
             * ScopedProxyMode 这个知识点比较复杂,需要结合web去理解
             * 可以暂时放一下,等说道springmvc的时候再说
             * 或者看情况现在说也是一样的
             */
            definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
            /**
             * 把上述的这个数据结构注册给registry
             * registy就是AnnotatonConfigApplicationContext
             * AnnotatonConfigApplicationContext在初始化的時候通過調用父類的構造方法
             * 實例化了一个DefaultListableBeanFactory
             * *registerBeanDefinition里面就是把definitionHolder这个数据结构包含的信息注册到
             * DefaultListableBeanFactory这个工厂
             */
          BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);//关键代码
     }

    我们看最后一行关键代码

    public static void registerBeanDefinition(
                BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
                throws BeanDefinitionStoreException {
    
            // Register bean definition under primary name.
            String beanName = definitionHolder.getBeanName();//获取beanName
            registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());//关键代码
    
            //别名,先不看
            // Register aliases for bean name, if any.
            String[] aliases = definitionHolder.getAliases();
            if (aliases != null) {
                for (String alias : aliases) {
                    registry.registerAlias(beanName, alias);
                }
            }
        }

    还是跟关键代码

    @Override
        public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
                throws BeanDefinitionStoreException {
    
            //DefaultListableBeanFactory
            this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
        }

    这里的beanFactory就是前文说的DefaultListableBeanFactory,继续跟

    @Override
        public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
                throws BeanDefinitionStoreException {
    
            Assert.hasText(beanName, "Bean name must not be empty");
            Assert.notNull(beanDefinition, "BeanDefinition must not be null");
    
            if (beanDefinition instanceof AbstractBeanDefinition) {//验证
                try {
                    ((AbstractBeanDefinition) beanDefinition).validate();
                }
                catch (BeanDefinitionValidationException ex) {
                    throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                            "Validation of bean definition failed", ex);
                }
            }
            //这里beanDefinitionMap是存储bean的name和.beanDefinition的map结果,此处有5个spring内置的BeanDefinition
            BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);//这里的beanName是配置类的名字,existingDefinition应该为null
            if (existingDefinition != null) {
                if (!isAllowBeanDefinitionOverriding()) {
                    throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
                }
                else if (existingDefinition.getRole() < beanDefinition.getRole()) {
                    // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
                    if (logger.isInfoEnabled()) {
                        logger.info("Overriding user-defined bean definition for bean '" + beanName +
                                "' with a framework-generated bean definition: replacing [" +
                                existingDefinition + "] with [" + beanDefinition + "]");
                    }
                }
                else if (!beanDefinition.equals(existingDefinition)) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Overriding bean definition for bean '" + beanName +
                                "' with a different definition: replacing [" + existingDefinition +
                                "] with [" + beanDefinition + "]");
                    }
                }
                else {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Overriding bean definition for bean '" + beanName +
                                "' with an equivalent definition: replacing [" + existingDefinition +
                                "] with [" + beanDefinition + "]");
                    }
                }
                this.beanDefinitionMap.put(beanName, beanDefinition);
            }
            else {//进这里
                if (hasBeanCreationStarted()) {//这里跳过,不进这里,先不看
                    // Cannot modify startup-time collection elements anymore (for stable iteration)
                    synchronized (this.beanDefinitionMap) {
                        this.beanDefinitionMap.put(beanName, beanDefinition);
                        List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
                        updatedDefinitions.addAll(this.beanDefinitionNames);
                        updatedDefinitions.add(beanName);
                        this.beanDefinitionNames = updatedDefinitions;
                        removeManualSingletonName(beanName);
                    }
                }
                else {//关键代码
                    // Still in startup registration phase
                    //这里的beanDefinitionMap是一个map,存放beanName,beanDefinition
                    this.beanDefinitionMap.put(beanName, beanDefinition);
                    //这里的beanDefinitionNames是一个list,存放beanName
                    this.beanDefinitionNames.add(beanName);
                    removeManualSingletonName(beanName);
                }
                this.frozenBeanDefinitionNames = null;
            }
    
            if (existingDefinition != null || containsSingleton(beanName)) {
                resetBeanDefinition(beanName);
            }
        }

    这里的关键代码,我标注出来了,就是上面那个bean工厂的默认实现的几个属性

    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
    
    private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
    
    //手动注册的单例对象的名称列表,按注册顺序排列
        /** List of names of manually registered singletons, in registration order. */
        private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);

    到这里register方法就结束了,大概是将我们的类解析成BeanDefinition,并存在bean工厂的beanDefinitionMap 属性中,后面就是refresh()方法了,这个方法太复杂,我们在后面分几个博客来研究他,先看一下源码吧

    @Override
        public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
    
                //准备工作包括设置启动时间,是否激活标识位,
                // 初始化属性源(property source)配置
                // Prepare this context for refreshing.
                prepareRefresh();
                //此处的beanFactory就是DefaultListableBeanFactory,有Map<String, BeanDefinition> beanDefinitionMap和List<String> beanDefinitionNames等属性
                // Tell the subclass to refresh the internal bean factory.
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
                // Prepare the bean factory for use in this context.
                //准备工厂
                prepareBeanFactory(beanFactory);
    
                try {
                    // Allows post-processing of the bean factory in context subclasses.
                    //目前是空方法,留给后续扩展
                    postProcessBeanFactory(beanFactory);
    
                    //完成扫描和解析(类--->beanDefinition)         beanDefinitionMap
                    // Invoke factory processors registered as beans in the context.
                    invokeBeanFactoryPostProcessors(beanFactory);
    
                    //注册beanPostProcessor
                    // Register bean processors that intercept bean creation.
                    registerBeanPostProcessors(beanFactory);
    
                    // Initialize message source for this context.
                    initMessageSource();
                    //初始化应用事件广播器
                    // Initialize event multicaster for this context.
                    initApplicationEventMulticaster();
    
                    // Initialize other special beans in specific context subclasses.
                    onRefresh();
    
                    // Check for listener beans and register them.
                    registerListeners();
    
                    //实例化所有单例的对象
                    // Instantiate all remaining (non-lazy-init) singletons.
                    finishBeanFactoryInitialization(beanFactory);
    
                    // Last step: publish corresponding event.
                    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();
                }
            }
        }

    好了,这篇文章到这里就结束了.谢谢大家的观看,大家有空的话就帮我点个赞吧
    文章中若有错误和疏漏之处,还请各位大佬不吝指出

  • 相关阅读:
    Yii增删改查
    10个超级有用、必须收藏的PHP代码样例
    yii源码分析I、II
    Yii源码阅读笔记
    Yii源码阅读笔记
    Yii源码阅读笔记
    当浏览器输入url的时候发生了什么
    js模块化值之seaJS
    js判断字符串中的英文和汉字
    display:table-cell的惊天作用,直接惊呆你!
  • 原文地址:https://www.cnblogs.com/lusaisai/p/12907796.html
Copyright © 2011-2022 走看看