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

时间:2022-12-28 08:22:23

一、代码实例

  如之前介绍的,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生命周期等