ApplicationContext作为IOC容器的实现时的源码跟踪

1.分析这行代码:

ApplicationContext beanFactory = new ClassPathXmlApplicationContext(“spring/springmvc.xml”);

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
    // 直接调用重载的方法
        this(new String[]{configLocation}, true, (ApplicationContext)null);
    }

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
        super(parent);
        //存储Springmvc.xml 路径   具体看1.1
        this.setConfigLocations(configLocations);
        if (refresh) {
        // 初始化的时候refresh==true,核心逻辑的开始 具体看1.2
            this.refresh();
        }
    }

1.1 存储xml文件路径。

// AbstractRefreshableConfigApplicationContext 类
public void setConfigLocations(String... locations) {
        if (locations != null) {
            Assert.noNullElements(locations, "Config locations must not be null");
            this.configLocations = new String[locations.length];
            for(int i = 0; i < locations.length; ++i) {
           // 把xml路径放入到 String[] configLocations 中,支持多个配置文件以数组方式同时传入。
                this.configLocations[i] = this.resolvePath(locations[i]).trim();
            }
        } else {
            this.configLocations = null;
        }

    }

1.2 refresh()方法 在AbstractApplicationContext类中

public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
        // 准备刷新上下文环境 具体看 1.3
            this.prepareRefresh();
            /*
        加载BeanFactory,ApplicationContext是对BeanFactory功能的扩展,这个方法就是用来获取BeanFactory
        具体看 1.4
        */
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);
            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

1.3 环境准备

// 实际这一段并没有做任何事,主要是为了扩展用的,spring本身并没有做任何事情
protected void prepareRefresh() {
        this.startupDate = System.currentTimeMillis();
        this.closed.set(false);
        this.active.set(true);
        if (this.logger.isInfoEnabled()) {
            this.logger.info("Refreshing " + this);
        }
        // 留给子类覆盖
        this.initPropertySources();
        // 验证需要的属性文件是否都已经放入环境中
        this.getEnvironment().validateRequiredProperties();
        this.earlyApplicationEvents = new LinkedHashSet();
    }

1.4 obtainFreshBeanFactory()具体实现 AbstractApplicationContext类

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    // 调用相同类下的 refreshBeanFactory()方法 具体看 1.4.1 
        this.refreshBeanFactory();
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
        }
        return beanFactory;
    }
1.4.1 refreshBeanFanctory() 在 AbstractRefreshableApplicationContext类中
protected final void refreshBeanFactory() throws BeansException {
    // 判断是否有BeanFactory,初始化的时候,是没有的,false
        if (this.hasBeanFactory()) {
            this.destroyBeans();
            this.closeBeanFactory();
        }
        try {
        // 创建DefaultListableBeanFactory, 
        // new DefaultListableBeanFactory(this.getInternalParentBeanFactory());
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
            beanFactory.setSerializationId(this.getId());
            // 定制BeanFactory 具体看1.4.1.1
            this.customizeBeanFactory(beanFactory);
            // 初始化 DocumetReader ,并进行XML文件读取及解析 具体看1.4.1.2
            this.loadBeanDefinitions(beanFactory);
            Object var2 = this.beanFactoryMonitor;
            synchronized(this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        } catch (IOException var5) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
        }
    }
1.4.1.1 定制化BeanFactory ,对BeanFactory进行功能扩展
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
        if (this.allowBeanDefinitionOverriding != null) {
                beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding.booleanValue());
        }
    // 是否允许bean之间存在循环依赖
        if (this.allowCircularReferences != null) {
            beanFactory.setAllowCircularReferences(this.allowCircularReferences.booleanValue());
        }

    }

1.4.1.2 初始化 DocumetReader ,并进行XML文件读取及解析 在AbstractXmlApplicationContext类

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
        // 初始化BeanFactoryReader ,实际上就是加如一个验证位
        this.initBeanDefinitionReader(beanDefinitionReader);
        // 这里XmlBeanFactory创建时一样,通过一个XmlBeanDefinitionReader来读取Xml
        this.loadBeanDefinitions(beanDefinitionReader);
    }

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
    // 检查ClassPathXmlApplicationContext中的 Resource[] configResources; 是否有资源,有就加载。
        Resource[] configResources = this.getConfigResources();
        if (configResources != null) {
            reader.loadBeanDefinitions(configResources);
        }
    /*
    检查AbstractRefreshableConfigApplicationContext中的String[] configLocations 中是否有资源
    前面在  this.setConfigLocations(configLocations); 中我们把传入的 spring\mvc.xml 路径存入进去了。
    */
        String[] configLocations = this.getConfigLocations();
        if (configLocations != null) {
        // 根据路径加载 BeanDefinition 到 DefaultListableBeanFactory中去了,
        // 具体实现参考 XmlBeanFactory的初始化
            reader.loadBeanDefinitions(configLocations);
        }
    }

至此,ApplicationContext中已经具有了XmlBeanFactory的功能。
即已经完成XmlBeanFactory的初始化,接下来看扩展。

2. 功能扩展 回到refresh()方法

public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
        // 准备刷新上下文环境 具体看 1.3
            this.prepareRefresh();
            /*
        加载BeanFactory,ApplicationContext是对BeanFactory功能的扩展,这个方法就是用来获取BeanFactory
        具体看 1.4
        */
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            // 在这之前,已经完成了对配置的解析。 ApplicationContext的功能扩展正式展开。
            // prepareBeanFactory 具体看 2.1
            this.prepareBeanFactory(beanFactory);
            try {

                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                // 注册beanFactory 中所有的BeanPostProcessor ,在前面prepareBeanFactory方法中,添加了几个
                // BeanPostProcessor ,但那里只是实现了,并添加。还没有注册,在这里进行注册。 
                // 具体 看 2.2
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                // 注册监听器 监听器利用了观察者模式,ApplicationCotext中注册观测者(监听器)
                this.registerListeners();
                // 初始化非延迟加载 这个是重点的重点 具体分析看 2.3
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

2.1 prepareBeanFactory() 在 AbstractApplicationContext

 protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
      // 设置beanFactory的classLoader为当前context的classLoader
        beanFactory.setBeanClassLoader(this.getClassLoader());
        // 设置beanFactory的表达式语言
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        /*
    增加对属性编辑器的支持,例如在SpringDI注入的时候,可以把普通属性注入进来,但是像Date类型就无法识别,
    就需要这个转换了,不过一般时间
    */
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
        // 添加BeanPostProcessor ,添加ApplicationContextAwareProcessor处理器
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        // 设置几个忽略自动装配的接口
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);
        // 可以看到有很多addBeanPostProcessor,那这个到底是什么呢? 具体看 2.1.1
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
        // 增加对AspectJ的支持
        if (beanFactory.containsBean("loadTimeWeaver")) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
    // 添加默认的系统环境bean
        if (!beanFactory.containsLocalBean("environment")) {
            beanFactory.registerSingleton("environment", this.getEnvironment());
        }

        if (!beanFactory.containsLocalBean("systemProperties")) {
            beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
        }

        if (!beanFactory.containsLocalBean("systemEnvironment")) {
            beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
        }

    }

2.1.1 BeanPostProcessor 接口

/*
从这个接口看,有两个方法,bean初始化前调用的方法,bean初始化后调用的方法。
每一个实现的BeanPostProcessor接口的类,都能在bean初始化前后,实现一些逻辑。
所以,Spring中大部分功能都是通过后处理器的方式进行扩展的。
*/
public interface BeanPostProcessor {
    Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;

    Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
}

2.2 注册BeanPostProcessor

public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
        // 使用priorityOrderedPostProcessors  保证顺序。
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList();
        List<String> orderedPostProcessorNames = new ArrayList();
        List<String> nonOrderedPostProcessorNames = new ArrayList();
        String[] var8 = postProcessorNames;
        int var9 = postProcessorNames.length;

        String ppName;
        BeanPostProcessor pp;
        for(int var10 = 0; var10 < var9; ++var10) {
            ppName = var8[var10];
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                }
            } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            } else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
        registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList();
        Iterator var14 = orderedPostProcessorNames.iterator();

        while(var14.hasNext()) {
            String ppName = (String)var14.next();
            BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }

        sortPostProcessors(beanFactory, orderedPostProcessors);
        registerBeanPostProcessors(beanFactory, (List)orderedPostProcessors);
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList();
        Iterator var17 = nonOrderedPostProcessorNames.iterator();

        while(var17.hasNext()) {
            ppName = (String)var17.next();
            pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }

        registerBeanPostProcessors(beanFactory, (List)nonOrderedPostProcessors);
        sortPostProcessors(beanFactory, internalPostProcessors);
        registerBeanPostProcessors(beanFactory, (List)internalPostProcessors);
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

2.3 初始化非延迟加载

都知道ApplicationContext相对于XmlBeanFactory的区别就在于ApplicationContext会在初始化容器的时候,把bean顺带也加载了,而XmlBeanFactory不会,只有用到的时候才会加载。 具体来分析这个方法

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
            beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
        }

        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
                public String resolveStringValue(String strVal) {
                    return AbstractApplicationContext.this.getEnvironment().resolvePlaceholders(strVal);
                }
            });
        }

        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        String[] var3 = weaverAwareNames;
        int var4 = weaverAwareNames.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            String weaverAwareName = var3[var5];
            this.getBean(weaverAwareName);
        }

        beanFactory.setTempClassLoader((ClassLoader)null);
        beanFactory.freezeConfiguration();
        // 核心初始化方法
        beanFactory.preInstantiateSingletons();
    }
// 实际加载bean的方法, 在 DefaulistableBeanFactory中。 这里和XmlBeanFactory一样,
// 通过getBean(beanName) 来实例化bean。
 public void preInstantiateSingletons() throws BeansException {
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Pre-instantiating singletons in " + this);
        }
    // 获取beanDefinitionNames 中 所有的beanName,为初始化准备
        List<String> beanNames = new ArrayList(this.beanDefinitionNames);
        Iterator var2 = beanNames.iterator();

        .....

        // 如果是FactoryBean,那就得到这个对象。
                if (this.isFactoryBean(beanName)) {
                    final FactoryBean<?> factory = (FactoryBean)this.getBean("&" + beanName);
                    boolean isEagerInit;
                    ......  // 这其中都是一堆的判断

                    if (isEagerInit) {
                        this.getBean(beanName);
                    }
                } else {
                // 前面都是各种判断,这里才是真正的实例化bean 的地方。
                    this.getBean(beanName);
                }
            }
        }
    }

2.4 getBean的逻辑加载

这里写图片描述
Bean的生命周期:
在实例化前后会有两个切面

在初始化前后会有两个切面

AbstractBeanFactory.doGetBean

其中逻辑太过复杂,就不写了,
主要就是:
1. 调用getBean
2. 判断是否可以实例化,(是单例对象,不是抽象类型,不是LazyInit)   是
3. 是否是FactoryBean    否
4. 查询singletonObject(一级缓存)中是否存在    否
5. 是否有父工厂
    - 是  获取其父工厂调用getBean
    - 否  下一步
6. 检查Bean对象是否有依赖关系
    - 有 获取所依赖的Bean对象
        - 这里有一个解决循环依赖的问题,会通过提前曝光实例,通过三级缓存来解决。
    - 否 下一步
7. 检查Bean对象是什么类型
    - 是single  调用自动装配工厂产生Bean对象实例。
    -Prototype 创建Bean对象实例。
8.返回bean对象实例,并将其存入到一级缓存。

猜你喜欢

转载自blog.csdn.net/mooneal/article/details/79716806