• [spring源码学习]七、IOC源码-Context


    一、代码实例

      如之前介绍的,spring中ioc是它最为核心的模块,前边花了大量时间分析spring的bean工厂和他如何生成bean,可是在我们实际应用中,很少直接使用beanFactory,因为spring提供了更好用的ApplicationContext接口,使用方法和bean工厂基本一致

            ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
            Person person=(Person)context.getBean("person");
            person.sayHello();

      那么我们来看下源代码中,我们ClassPathXmlApplicationContext为目标,分析它做了哪些工作。

    二、源码分析

      1、进入ClassPathXmlApplicationContext,我们可以看到他提供了各种重构方法,其中配置文件路径可以支持:字符串,可变字符串,数组

        public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
            this(new String[] {configLocation}, true, null);
        }
        public ClassPathXmlApplicationContext(String... configLocations) throws BeansException {
            this(configLocations, true, null);
        }
        public ClassPathXmlApplicationContext(String[] configLocations, ApplicationContext parent) throws BeansException {
            this(configLocations, true, parent);
        }
        public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh) throws BeansException {
            this(configLocations, refresh, null);
        }

      2、进入refresh方法,首先竹本refresh环境,

        protected void prepareRefresh() {
            this.startupDate = System.currentTimeMillis();
            this.closed.set(false);
            this.active.set(true);
    
            if (logger.isInfoEnabled()) {
                logger.info("Refreshing " + this);
            }
    
            // Initialize any placeholder property sources in the context environment
            initPropertySources();
    
            // Validate that all properties marked as required are resolvable
            // see ConfigurablePropertyResolver#setRequiredProperties
            getEnvironment().validateRequiredProperties();
    
            // Allow for the collection of early ApplicationEvents,
            // to be published once the multicaster is available...
            this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
        }

      3、调用ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()

        protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
            refreshBeanFactory();
            ConfigurableListableBeanFactory beanFactory = getBeanFactory();
            if (logger.isDebugEnabled()) {
                logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
            }
            return beanFactory;
        }

      4、调用refreshBeanFactory方法,可以看到里边的几个步骤

      a)生产beanfactory,如果有父类,继承父类

      b)设置序列化id

      c)customizeBeanFactory,暂时不知道用处

      d)loadBeanDefinitions(beanFactory)最终调用了loadBeanDefinitions(beanDefinitionReader)方法

      可见在此步骤已经完成了对xml文件的读取,并解析为最终的beanDefinition

    protected final void refreshBeanFactory() throws BeansException {
            if (hasBeanFactory()) {
                destroyBeans();
                closeBeanFactory();
            }
            try {
                DefaultListableBeanFactory beanFactory = createBeanFactory();
                beanFactory.setSerializationId(getId());
                customizeBeanFactory(beanFactory);
                loadBeanDefinitions(beanFactory);
                synchronized (this.beanFactoryMonitor) {
                    this.beanFactory = beanFactory;
                }
            }
            catch (IOException ex) {
                throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
            }
        }

      5、prepareBeanFactory设置各种BeanFactory的参数

      6、invokeBeanFactoryPostProcessors调用BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的方法

      7、查找是否有initMessageSource为id的bean,如果没有,创建默认的

      8、查找是否有id为applicationEventMulticaster的bean,如果没有,创建默认,设置为congtext的applicationEventMulticaster

        protected void initApplicationEventMulticaster() {
            ConfigurableListableBeanFactory beanFactory = getBeanFactory();
            //查找是否包含名为applicationEventMulticaster的bean,如果没有,创建默认的
            if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
                this.applicationEventMulticaster =
                        beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
                if (logger.isDebugEnabled()) {
                    logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
                }
            }
            else {
                this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
                beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
                if (logger.isDebugEnabled()) {
                    logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                            APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                            "': using default [" + this.applicationEventMulticaster + "]");
                }
            }
        }

      9、查找注册的ApplicationListener,设置到applicationEventMulticaster中

        protected void registerListeners() {
            // Register statically specified listeners first.
            //查找手动设置的ApplicationListener,设置到applicationEventMulticaster中
            for (ApplicationListener<?> listener : getApplicationListeners()) {
                getApplicationEventMulticaster().addApplicationListener(listener);
            }
    
            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let post-processors apply to them!
            //根据beanType查询ApplicationListener,设置到applicationEventMulticaster中
            String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
            for (String listenerBeanName : listenerBeanNames) {
                getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
            }
    
            // Publish early application events now that we finally have a multicaster...
            Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
            //查询是否有需要立即通知的事件,进行通知
            this.earlyApplicationEvents = null;
            if (earlyEventsToProcess != null) {
                for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                    getApplicationEventMulticaster().multicastEvent(earlyEvent);
                }
            }
        }

      10、查找是否有id为conversionService的bean,如果有,设置进beanFactory

            //查找是否有id为conversionService的bean,如果有,设置进beanFactory
            if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                    beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
                beanFactory.setConversionService(
                        beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
            }

      11、查找是否有embeddedValueResolvers,值的解析器,没有默认注入string解析

            //查找是否有embeddedValueResolvers,值的解析器,没有默认注入string解析
            if (!beanFactory.hasEmbeddedValueResolver()) {
                beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
                    @Override
                    public String resolveStringValue(String strVal) {
                        return getEnvironment().resolvePlaceholders(strVal);
                    }
                });
            }

      12、查找类型为LoadTimeWeaverAware的解析,有的话进行获取,并没有进一步使用,应该只是起到初始化作用

            //查找类型为LoadTimeWeaverAware的解析,有的话进行获取,并没有进一步使用,应该只是起到初始化作用
            String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
            for (String weaverAwareName : weaverAwareNames) {
                getBean(weaverAwareName);
            }

      13、进入preInstantiateSingletons方法,初始化所有的bean

    for (String beanName : beanNames) {
                RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
                if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                    //判断是否工厂bean
                    if (isFactoryBean(beanName)) {
                        final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                                @Override
                                public Boolean run() {
                                    return ((SmartFactoryBean<?>) factory).isEagerInit();
                                }
                            }, getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean &&
                                    ((SmartFactoryBean<?>) factory).isEagerInit());
                        }
                        if (isEagerInit) {
                            getBean(beanName);
                        }
                    }
                    else {
                        //进行实例化
                        getBean(beanName);
                    }
                }
            }

      14、已经初始化的bean,并且继承了SmartInitializingSingleton接口,执行它的afterSingletonsInstantiated方法

    //已经初始化的bean,并且继承了SmartInitializingSingleton接口,执行它的afterSingletonsInstantiated方法
            for (String beanName : beanNames) {
                Object singletonInstance = getSingleton(beanName);
                if (singletonInstance instanceof SmartInitializingSingleton) {
                    final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                    if (System.getSecurityManager() != null) {
                        AccessController.doPrivileged(new PrivilegedAction<Object>() {
                            @Override
                            public Object run() {
                                smartSingleton.afterSingletonsInstantiated();
                                return null;
                            }
                        }, getAccessControlContext());
                    }
                    else {
                        smartSingleton.afterSingletonsInstantiated();
                    }
                }
            }

      15、调用finishRefresh,完成bean的刷新,第一步initLifecycleProcessor初始化bean的生命后周期bean

    protected void initLifecycleProcessor() {
            ConfigurableListableBeanFactory beanFactory = getBeanFactory();
            //获取id为lifecycleProcessor的bean,如果没有,创建默认的
            if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
                this.lifecycleProcessor =
                        beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
                if (logger.isDebugEnabled()) {
                    logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
                }
            }
            else {
                DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
                defaultProcessor.setBeanFactory(beanFactory);
                this.lifecycleProcessor = defaultProcessor;
                beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
                if (logger.isDebugEnabled()) {
                    logger.debug("Unable to locate LifecycleProcessor with name '" +
                            LIFECYCLE_PROCESSOR_BEAN_NAME +
                            "': using default [" + this.lifecycleProcessor + "]");
                }
            }
        }

      16、getLifecycleProcessor().onRefresh()方法,启动特定bean

    private void startBeans(boolean autoStartupOnly) {
            Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
            //获取所有继承了Lifecycle的SmartLifecycle,并且自动启动且phase不为空,那么执行start方法
            Map<Integer, LifecycleGroup> phases = new HashMap<Integer, LifecycleGroup>();
            for (Map.Entry<String, ? extends Lifecycle> entry : lifecycleBeans.entrySet()) {
                Lifecycle bean = entry.getValue();
                if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
                    int phase = getPhase(bean);
                    LifecycleGroup group = phases.get(phase);
                    if (group == null) {
                        group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
                        phases.put(phase, group);
                    }
                    group.add(entry.getKey(), bean);
                }
            }
            if (phases.size() > 0) {
                List<Integer> keys = new ArrayList<Integer>(phases.keySet());
                Collections.sort(keys);
                for (Integer key : keys) {
                    phases.get(key).start();
                }
            }
        }

      17、广播容器刷新事件publishEvent(new ContextRefreshedEvent(this))

    protected void publishEvent(Object event, ResolvableType eventType) {
            Assert.notNull(event, "Event must not be null");
            if (logger.isTraceEnabled()) {
                logger.trace("Publishing event in " + getDisplayName() + ": " + event);
            }
    
            // Decorate event as an ApplicationEvent if necessary
            ApplicationEvent applicationEvent;
            if (event instanceof ApplicationEvent) {
                applicationEvent = (ApplicationEvent) event;
            }
            else {
                applicationEvent = new PayloadApplicationEvent<Object>(this, event);
                if (eventType == null) {
                    eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType();
                }
            }
    
            // Multicast right now if possible - or lazily once the multicaster is initialized
            if (this.earlyApplicationEvents != null) {
                //如果有预制行添加到预制行,预制行在执行一次后被置为null,以后都是直接执行
                this.earlyApplicationEvents.add(applicationEvent);
            }
            else {
                //广播event时间
                getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
            }
    
            // Publish event via parent context as well...
            //父bean同样广播
            if (this.parent != null) {
                if (this.parent instanceof AbstractApplicationContext) {
                    ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
                }
                else {
                    this.parent.publishEvent(event);
                }
            }
        }

      18、到此,我们完成了整个初始化过程,获取bean时候,流程基本不变

    三、总结

      我们可以看到,与beanfactory相比,context有以下特点:

      1、在基本的解析文件生成beanDefinition过程其实两者是一致的,都是解析了xml的配置后生成了配置文件放到了beanDefinitionMap中

      2、在beanFactory中的,bean是在第一次getBean的时候进行生成,所以配置lazy-init延迟加载并不会起作用,因为全部bean都是延迟加载的。在context中,会在解析完成后的preInstantiateSingletons方法中调用getBean初始化所有的非lazy-init且单例模式的bean

      3、在context中内置了许多的bean,他们要求开发者必须按照系统约定的命名规则进行命名,这样可以在系统内部组成特定的功能,如果开发者没有定义这些bean,系统也会默认生成一个bean,这些bean主要有:messageSource、applicationEventMulticaster、conversionService、embeddedValueResolvers、lifecycleProcessor,也有一些指定了接口实现的bean如:LoadTimeWeaverAware、SmartInitializingSingleton。这些类完善了bean的整个流程,使得ioc容器可以读取配置文件,管理通知,bean生命周期等

  • 相关阅读:
    linux驱动程序之电源管理之标准linux休眠与唤醒机制分析(一)
    linux驱动程序之电源管理 之linux休眠与唤醒(2)
    linux驱动程序之电源管理之regulator机制流程 (1)
    ARM--存储管理器
    元朝皇帝列表 元朝历代皇帝简介
    linux下valgrind的使用概述
    linux之sort用法
    python的ftplib模块
    Python使用struct处理二进制(pack和unpack用法)
    Python使用struct处理二进制(pack和unpack用法)
  • 原文地址:https://www.cnblogs.com/jyyzzjl/p/5462349.html
Copyright © 2020-2023  润新知