Spring上下文加载监听器ContextLoaderListener--源码解析

一般在web应用配置Spring上下文如下,那么ContextLoaderListener到底做了什么呢,我们来看一下
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring/ApplicationContext.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
ruid/*</url-pattern>
</web-app>

//上下文加载监听器
public class ContextLoaderListener extends ContextLoader
    implements ServletContextListener
{
    public ContextLoaderListener(WebApplicationContext context)
    {
        super(context);
    }
    public void contextInitialized(ServletContextEvent event)
    {
        //初始化WebApplicationContext
        initWebApplicationContext(event.getServletContext());
    }
    public void contextDestroyed(ServletContextEvent event)
    {
        closeWebApplicationContext(event.getServletContext());
        ContextCleanupListener.cleanupAttributes(event.getServletContext());
    }
}

//上下文加载器
public class ContextLoader
{
    public ContextLoader(WebApplicationContext context)
    {
        this.context = context;
    } 
    public WebApplicationContext initWebApplicationContext(ServletContext servletContext)
    {
        Log logger;
        long startTime;
	//如果servletContext的WebApplicationContext.root属性存在,则抛出根应用上下文已经初始化异常
        if(servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null)
            throw new IllegalStateException("Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!");
        logger = LogFactory.getLog(org/springframework/web/context/ContextLoader);
        servletContext.log("Initializing Spring root WebApplicationContext");
        if(logger.isInfoEnabled())
            logger.info("Root WebApplicationContext: initialization started");
        startTime = System.currentTimeMillis();
        if(context == null)
            context = createWebApplicationContext(servletContext);
        if(context instanceof ConfigurableWebApplicationContext)
        {
            ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)context;
            if(!cwac.isActive())
            {
                if(cwac.getParent() == null)
                {
		    //加载应用上下文
                    ApplicationContext parent = loadParentContext(servletContext);
		    //设置web上下文的父上下文
                    cwac.setParent(parent);
                }
		//设置并刷新WebApplicationContext
                configureAndRefreshWebApplicationContext(cwac, servletContext);
            }
        }
	//设置WebApplicationContext的root属性
        servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, context);
        ClassLoader ccl = Thread.currentThread().getContextClassLoader();
        if(ccl == org/springframework/web/context/ContextLoader.getClassLoader())
            currentContext = context;
        else
        if(ccl != null)
	    //设置当前线程的上下文
            currentContextPerThread.put(ccl, context);
        if(logger.isDebugEnabled())
            logger.debug((new StringBuilder()).append("Published root WebApplicationContext as ServletContext attribute with name [").append(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE).append("]").toString());
        if(logger.isInfoEnabled())
        {
            long elapsedTime = System.currentTimeMillis() - startTime;
            logger.info((new StringBuilder()).append("Root WebApplicationContext: initialization completed in ").append(elapsedTime).append(" ms").toString());
        }
        return context;
        RuntimeException ex;
        ex;
        logger.error("Context initialization failed", ex);
        servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
        throw ex;
        Error err;
        err;
        logger.error("Context initialization failed", err);
        servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
        throw err;
    }
    //创建WebApplicationContext
     protected WebApplicationContext createWebApplicationContext(ServletContext sc)
    {
        Class contextClass = determineContextClass(sc);
        if(!org/springframework/web/context/ConfigurableWebApplicationContext.isAssignableFrom(contextClass))
            throw new ApplicationContextException((new StringBuilder()).append("Custom context class [").append(contextClass.getName()).append("] is not of type [").append(org/springframework/web/context/ConfigurableWebApplicationContext.getName()).append("]").toString());
        else
            return (ConfigurableWebApplicationContext)BeanUtils.instantiateClass(contextClass);
    }
    //获取ContextClass
    protected Class determineContextClass(ServletContext servletContext)
    {
        String contextClassName;
        contextClassName = servletContext.getInitParameter("contextClass");
        if(contextClassName == null)
            break MISSING_BLOCK_LABEL_55;
        return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader());
        throw new ApplicationContextException((new StringBuilder()).append("Failed to load custom context class [").append(contextClassName).append("]").toString(), ex);
        contextClassName = defaultStrategies.getProperty(org/springframework/web/context/WebApplicationContext.getName());
        return ClassUtils.forName(contextClassName, org/springframework/web/context/ContextLoader.getClassLoader());
        throw new ApplicationContextException((new StringBuilder()).append("Failed to load default context class [").append(contextClassName).append("]").toString(), ex);
    }
     //加载应用上下文
     protected ApplicationContext loadParentContext(ServletContext servletContext)
    {
        ApplicationContext parentContext = null;
        String locatorFactorySelector = servletContext.getInitParameter("locatorFactorySelector");
        String parentContextKey = servletContext.getInitParameter("parentContextKey");
        if(parentContextKey != null)
        {
            BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector);
            Log logger = LogFactory.getLog(org/springframework/web/context/ContextLoader);
            if(logger.isDebugEnabled())
                logger.debug((new StringBuilder()).append("Getting parent context definition: using parent context key of '").append(parentContextKey).append("' with BeanFactoryLocator").toString());
            parentContextRef = locator.useBeanFactory(parentContextKey);
	    //获取父应用上下文
            parentContext = (ApplicationContext)parentContextRef.getFactory();
        }
        return parentContext;
    }
    //设置并刷新WebApplicationContext
     protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc)
    {
        if(ObjectUtils.identityToString(wac).equals(wac.getId()))
        {
            String idParam = sc.getInitParameter("contextId");
            if(idParam != null)
                wac.setId(idParam);
            else
                wac.setId((new StringBuilder()).append(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX).append(ObjectUtils.getDisplayString(sc.getContextPath())).toString());
        }
	//设置web上下文的ServletContext
        wac.setServletContext(sc);
	//获取上下文位置
        String configLocationParam = sc.getInitParameter("contextConfigLocation");
        if(configLocationParam != null)
            wac.setConfigLocation(configLocationParam);
        ConfigurableEnvironment env = wac.getEnvironment();
        if(env instanceof ConfigurableWebEnvironment)

            ((ConfigurableWebEnvironment)env).initPropertySources(sc, null);
        customizeContext(sc, wac);
        //bean容器初始化,关键
        wac.refresh();
    }
     protected void customizeContext(ServletContext sc, ConfigurableWebApplicationContext wac)
    {
        List initializerClasses = determineContextInitializerClasses(sc);
        if(initializerClasses.isEmpty())
            return;
        ArrayList initializerInstances = new ArrayList();
        Class initializerClass;
        for(Iterator iterator = initializerClasses.iterator(); iterator.hasNext(); initializerInstances.add(BeanUtils.instantiateClass(initializerClass)))
        {
            initializerClass = (Class)iterator.next();
	    //解决初始化类,类型问题
            Class initializerContextClass = GenericTypeResolver.resolveTypeArgument(initializerClass, org/springframework/context/ApplicationContextInitializer);
            if(initializerContextClass != null)
                Assert.isAssignable(initializerContextClass, wac.getClass(), String.format("Could not add context initializer [%s] since its generic parameter [%s] is not assignable from the type of application context used by this context loader [%s]: ", new Object[] {
                    initializerClass.getName(), initializerContextClass.getName(), wac.getClass().getName()
                }));
        }
        AnnotationAwareOrderComparator.sort(initializerInstances);
        ApplicationContextInitializer initializer;
        for(Iterator iterator1 = initializerInstances.iterator(); iterator1.hasNext(); initializer.initialize(wac))
            initializer = (ApplicationContextInitializer)iterator1.next();

    }
    //获取需要上下文需要初始化的类
    protected List determineContextInitializerClasses(ServletContext servletContext)
    {
        List classes = new ArrayList();
        String globalClassNames = servletContext.getInitParameter("globalInitializerClasses");
        if(globalClassNames != null)
        {
            String as[] = StringUtils.tokenizeToStringArray(globalClassNames, ",; \t\n");
            int i = as.length;
            for(int j = 0; j < i; j++)
            {
                String className = as[j];
                classes.add(loadInitializerClass(className));
            }
        }
        String localClassNames = servletContext.getInitParameter("contextInitializerClasses");
        if(localClassNames != null)
        {
            String as1[] = StringUtils.tokenizeToStringArray(localClassNames, ",; \t\n");
            int k = as1.length;
            for(int l = 0; l < k; l++)
            {
                String className = as1[l];
                classes.add(loadInitializerClass(className));
            }
        }
        return classes;
    }
    //根据className获取需要加载的Class
       private Class loadInitializerClass(String className)
    {
        Class clazz;
        clazz = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader());
        Assert.isAssignable(org/springframework/context/ApplicationContextInitializer, clazz);
        return clazz;
        ClassNotFoundException ex;
        ex;
        throw new ApplicationContextException((new StringBuilder()).append("Failed to load context initializer class [").append(className).append("]").toString(), ex);
    }
    public static final String CONTEXT_ID_PARAM = "contextId";
    public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
    public static final String CONTEXT_CLASS_PARAM = "contextClass";
    public static final String CONTEXT_INITIALIZER_CLASSES_PARAM = "contextInitializerClasses";
    public static final String GLOBAL_INITIALIZER_CLASSES_PARAM = "globalInitializerClasses";
    public static final String LOCATOR_FACTORY_SELECTOR_PARAM = "locatorFactorySelector";
    public static final String LOCATOR_FACTORY_KEY_PARAM = "parentContextKey";
    private static final String INIT_PARAM_DELIMITERS = ",; \t\n";
    private static final String DEFAULT_STRATEGIES_PATH = "ContextLoader.properties";
    private static final Properties defaultStrategies;
    private static final Map currentContextPerThread = new ConcurrentHashMap(1);
    private static volatile WebApplicationContext currentContext;
    private WebApplicationContext context;//web应用上下恩
    private BeanFactoryReference parentContextRef;//父上下文的bean工厂引用

    static 
    {
        try
        {  //创建上下文配置文件资源
            ClassPathResource resource = new ClassPathResource("ContextLoader.properties", org/springframework/web/context/ContextLoader);
            //加载上下文配置文件
	    defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
        }
        catch(IOException ex)
        {
            throw new IllegalStateException((new StringBuilder()).append("Could not load 'ContextLoader.properties': ").append(ex.getMessage()).toString());
        }
    }
}

//抽象应用上下文
public abstract class AbstractApplicationContext extends DefaultResourceLoader
    implements ConfigurableApplicationContext, DisposableBean
{

    public AbstractApplicationContext()
    {
        logger = LogFactory.getLog(getClass());
        id = ObjectUtils.identityToString(this);
        displayName = ObjectUtils.identityToString(this);
        beanFactoryPostProcessors = new ArrayList();
        active = false;
        closed = false;
        activeMonitor = new Object();
        startupShutdownMonitor = new Object();
        applicationListeners = new LinkedHashSet();
        resourcePatternResolver = getResourcePatternResolver();
    }

    public AbstractApplicationContext(ApplicationContext parent)
    {
        this();
        setParent(parent);
    }
    //设置父应用上下文
    public void setParent(ApplicationContext parent)
    {
        this.parent = parent;
        if(parent != null)
        {
            Environment parentEnvironment = parent.getEnvironment();
            if(parentEnvironment instanceof ConfigurableEnvironment)
                getEnvironment().merge((ConfigurableEnvironment)parentEnvironment);
        }
    }
      public void refresh()
        throws BeansException, IllegalStateException
    {
        synchronized(startupShutdownMonitor)
        {
	    //准备刷新
            prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
	     //bean容器准备工作
            prepareBeanFactory(beanFactory);
            try
            {
	       //bean后置处理器配置
                postProcessBeanFactory(beanFactory);
	        //bean容器解析构造bean,关键
                invokeBeanFactoryPostProcessors(beanFactory);
                registerBeanPostProcessors(beanFactory);
		 //初始化消息源
                initMessageSource();
                initApplicationEventMulticaster();
                onRefresh();
		//注册应用监听器
                registerListeners();
		//初始化bean容器
                finishBeanFactoryInitialization(beanFactory);
                finishRefresh();
            }
            catch(BeansException ex)
            {
                destroyBeans();
                cancelRefresh(ex);
                throw ex;
            }
        }
    }
    //准备刷新
    protected void prepareRefresh()
    {
        startupDate = System.currentTimeMillis();
        synchronized(activeMonitor)
        {
            active = true;
        }
        if(logger.isInfoEnabled())
            logger.info((new StringBuilder()).append("Refreshing ").append(this).toString());
	//初始化属性员
        initPropertySources();
	//校验必须的属性
        getEnvironment().validateRequiredProperties();
    }
     protected void initPropertySources()
    {
    }
    //获取ConfigurableListableBeanFactory
    protected ConfigurableListableBeanFactory obtainFreshBeanFactory()
    {
        refreshBeanFactory();
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if(logger.isDebugEnabled())
            logger.debug((new StringBuilder()).append("Bean factory for ").append(getDisplayName()).append(": ").append(beanFactory).toString());
        return beanFactory;
    }
   //获取内部父bean容器
   protected BeanFactory getInternalParentBeanFactory()
    {
        return ((BeanFactory) ((getParent() instanceof ConfigurableApplicationContext) ? ((ConfigurableApplicationContext)getParent()).getBeanFactory() : getParent()));
    }
    //bean容器准备工作
     protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory)
    {
        //bean容器类加载器
        beanFactory.setBeanClassLoader(getClassLoader());
	//bean容器Expression解决器
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
	//添加bean后置处理器
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        beanFactory.ignoreDependencyInterface(org/springframework/context/ResourceLoaderAware);
        beanFactory.ignoreDependencyInterface(org/springframework/context/ApplicationEventPublisherAware);
        beanFactory.ignoreDependencyInterface(org/springframework/context/MessageSourceAware);
        beanFactory.ignoreDependencyInterface(org/springframework/context/ApplicationContextAware);
        beanFactory.ignoreDependencyInterface(org/springframework/context/EnvironmentAware);
        beanFactory.registerResolvableDependency(org/springframework/beans/factory/BeanFactory, beanFactory);
        beanFactory.registerResolvableDependency(org/springframework/core/io/ResourceLoader, this);
        beanFactory.registerResolvableDependency(org/springframework/context/ApplicationEventPublisher, this);
        beanFactory.registerResolvableDependency(org/springframework/context/ApplicationContext, this);
        if(beanFactory.containsBean("loadTimeWeaver"))
        {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
        if(!beanFactory.containsLocalBean("environment"))
            beanFactory.registerSingleton("environment", getEnvironment());
        if(!beanFactory.containsLocalBean("systemProperties"))
            beanFactory.registerSingleton("systemProperties", getEnvironment().getSystemProperties());
        if(!beanFactory.containsLocalBean("systemEnvironment"))
            beanFactory.registerSingleton("systemEnvironment", getEnvironment().getSystemEnvironment());
    }

    //bean后置处理器配置
     protected void postProcessBeanFactory(ConfigurableListableBeanFactory configurablelistablebeanfactory)
    {
    }
    //bean容器解析构造bean
     protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory)
    {
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    }
    //初始化消息源
    protected void initMessageSource()
    {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if(beanFactory.containsLocalBean("messageSource"))
        {
            messageSource = (MessageSource)beanFactory.getBean("messageSource", org/springframework/context/MessageSource);
            if(parent != null && (messageSource instanceof HierarchicalMessageSource))
            {
                HierarchicalMessageSource hms = (HierarchicalMessageSource)messageSource;
                if(hms.getParentMessageSource() == null)
                    hms.setParentMessageSource(getInternalParentMessageSource());
            }
            if(logger.isDebugEnabled())
                logger.debug((new StringBuilder()).append("Using MessageSource [").append(messageSource).append("]").toString());
        } else
        {
            DelegatingMessageSource dms = new DelegatingMessageSource();
            dms.setParentMessageSource(getInternalParentMessageSource());
            messageSource = dms;
            beanFactory.registerSingleton("messageSource", messageSource);
            if(logger.isDebugEnabled())
                logger.debug((new StringBuilder()).append("Unable to locate MessageSource with name 'messageSource': using default [").append(messageSource).append("]").toString());
        }
    }
     protected void onRefresh()
        throws BeansException
    {
    }
    //注册应用监听器
    protected void registerListeners()
    {
        ApplicationListener listener;
        for(Iterator iterator = getApplicationListeners().iterator(); iterator.hasNext(); getApplicationEventMulticaster().addApplicationListener(listener))
            listener = (ApplicationListener)iterator.next();

        String listenerBeanNames[] = getBeanNamesForType(org/springframework/context/ApplicationListener, true, false);
        String as[] = listenerBeanNames;
        int i = as.length;
        for(int j = 0; j < i; j++)
        {
            String lisName = as[j];
            getApplicationEventMulticaster().addApplicationListenerBean(lisName);
        }
    }
    //初始化bean容器
    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)
    {
        if(beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", org/springframework/core/convert/ConversionService))
            beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", org/springframework/core/convert/ConversionService));
        String weaverAwareNames[] = beanFactory.getBeanNamesForType(org/springframework/context/weaving/LoadTimeWeaverAware, false, false);
        String as[] = weaverAwareNames;
        int i = as.length;
        for(int j = 0; j < i; j++)
        {
            String weaverAwareName = as[j];
            getBean(weaverAwareName);
        }

        beanFactory.setTempClassLoader(null);
        beanFactory.freezeConfiguration();
        beanFactory.preInstantiateSingletons();
    }

    public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";
    public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor";
    public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
    protected final Log logger;
    private String id;
    private String displayName;
    private ApplicationContext parent;
    private final List beanFactoryPostProcessors;//bean后置处理器
    private long startupDate;
    private boolean active;
    private boolean closed;
    private final Object activeMonitor;//激活同步监控锁
    private final Object startupShutdownMonitor;//启动关闭同步监控锁
    private Thread shutdownHook;
    private ResourcePatternResolver resourcePatternResolver;//资源解决其
    private LifecycleProcessor lifecycleProcessor;
    private MessageSource messageSource;//国际化消息处理
    private ApplicationEventMulticaster applicationEventMulticaster;
    private Set applicationListeners;
    private ConfigurableEnvironment environment;

    static 
    {
        org/springframework/context/event/ContextClosedEvent.getName();
    }
}

//AbstractRefreshableApplicationContext
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext
{
 //刷新bean容器
 protected final void refreshBeanFactory()
        throws BeansException
    {
        if(hasBeanFactory())
        {
            destroyBeans();
            closeBeanFactory();
        }
        try
        {
	    //创建bean容器
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            beanFactory.setSerializationId(getId());
	     //定制bean容器
            customizeBeanFactory(beanFactory);
            loadBeanDefinitions(beanFactory);
            synchronized(beanFactoryMonitor)
            {
                this.beanFactory = beanFactory;
            }
        }
    }
    //创建bean容器
     protected DefaultListableBeanFactory createBeanFactory()
    {
        return new DefaultListableBeanFactory(getInternalParentBeanFactory());
    }
    //定制bean容器
    protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory)
    {
        if(allowBeanDefinitionOverriding != null)
            beanFactory.setAllowBeanDefinitionOverriding(allowBeanDefinitionOverriding.booleanValue());
        if(allowCircularReferences != null)
	    //是否允许环路引用
            beanFactory.setAllowCircularReferences(allowCircularReferences.booleanValue());
    }
    //加载bean容器定义
    protected abstract void loadBeanDefinitions(DefaultListableBeanFactory defaultlistablebeanfactory)
        throws BeansException, IOException;
    private Boolean allowBeanDefinitionOverriding;
    private Boolean allowCircularReferences;
    private DefaultListableBeanFactory beanFactory;
    private final Object beanFactoryMonitor;
}

//默认bean容器
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
    implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable
{
    private static Class javaxInjectProviderClass = null;
    private static final Map serializableFactories = new ConcurrentHashMap(8);
    private String serializationId;
    private boolean allowBeanDefinitionOverriding;
    private boolean allowEagerClassLoading;
    private Comparator dependencyComparator;
    private AutowireCandidateResolver autowireCandidateResolver;
    private final Map resolvableDependencies;
    private final Map beanDefinitionMap;//bean定义
    private final Map allBeanNamesByType;
    private final Map singletonBeanNamesByType;//单例bean
    private final List beanDefinitionNames;//beanNames,List
    private boolean configurationFrozen;
    private String frozenBeanDefinitionNames[];
    static 
    {
        try
        {
            javaxInjectProviderClass = ClassUtils.forName("javax.inject.Provider", org/springframework/beans/factory/support/DefaultListableBeanFactory.getClassLoader());
        }
    }

}
//bean注册代理
class PostProcessorRegistrationDelegate
{
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors)
    {
        Set processedBeans = new HashSet();
        if(beanFactory instanceof BeanDefinitionRegistry)
        {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
            List regularPostProcessors = new LinkedList();
            List registryPostProcessors = new LinkedList();
            for(Iterator iterator = beanFactoryPostProcessors.iterator(); iterator.hasNext();)
            {
                BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)iterator.next();
                if(postProcessor instanceof BeanDefinitionRegistryPostProcessor)
                {
                    BeanDefinitionRegistryPostProcessor registryPostProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
                    registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryPostProcessors.add(registryPostProcessor);
                } else
                {
                    regularPostProcessors.add(postProcessor);
                }
            }
            for(boolean reiterate = true; reiterate;)
            {
                reiterate = false;
                postProcessorNames = beanFactory.getBeanNamesForType(org/springframework/beans/factory/support/BeanDefinitionRegistryPostProcessor, true, false);
                String as3[] = postProcessorNames;
                int k1 = as3.length;
                int l1 = 0;
                while(l1 < k1) 
                {
                    String ppName = as3[l1];
                    if(!processedBeans.contains(ppName))
                    {
                        BeanDefinitionRegistryPostProcessor pp = (BeanDefinitionRegistryPostProcessor)beanFactory.getBean(ppName, org/springframework/beans/factory/support/BeanDefinitionRegistryPostProcessor);
                        registryPostProcessors.add(pp);
                        processedBeans.add(ppName);
			//注册bean,关键在这
                        pp.postProcessBeanDefinitionRegistry(registry);
                        reiterate = true;
                    }
                    l1++;
                }
            }
    }
}

//bean配置处理器
public class ConfigurationClassPostProcessor
    implements BeanDefinitionRegistryPostProcessor, PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware
{
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
    {
        if(factoriesPostProcessed.contains(Integer.valueOf(registryId)))
        {
            throw new IllegalStateException((new StringBuilder()).append("postProcessBeanFactory already called for this post-processor against ").append(registry).toString());
        } else
        {
            //处理bean的定义
            processConfigBeanDefinitions(registry);
        }
    }
     public void processConfigBeanDefinitions(BeanDefinitionRegistry registry)
    {
        Set configCandidates = new LinkedHashSet();
        String as[] = registry.getBeanDefinitionNames();
        int i = as.length;
        for(int j = 0; j < i; j++)
        {
            String beanName = as[j];
            BeanDefinition beanDef = registry.getBeanDefinition(beanName);
            if(ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, metadataReaderFactory))
                configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
        }
        ConfigurationClassParser parser = new ConfigurationClassParser(metadataReaderFactory, problemReporter, environment, resourceLoader, componentScanBeanNameGenerator, registry);
       //根据bean配置,解析bean
	parser.parse(configCandidates);
        parser.validate();
    }
}

//bean配置解析
class ConfigurationClassParser
{
   public ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory, ProblemReporter problemReporter, Environment environment, ResourceLoader resourceLoader, BeanNameGenerator componentScanBeanNameGenerator, BeanDefinitionRegistry registry)
    {
        this.metadataReaderFactory = metadataReaderFactory;
        this.problemReporter = problemReporter;
        this.environment = environment;
        this.resourceLoader = resourceLoader;
        this.registry = registry;
	//组件注解扫面解析器
        componentScanParser = new ComponentScanAnnotationParser(resourceLoader, environment, componentScanBeanNameGenerator, registry);
        conditionEvaluator = new ConditionEvaluator(registry, environment, resourceLoader);
    }
    //根据bean配置,解析bean
     public void parse(Set configCandidates)
    {
        for(Iterator iterator = configCandidates.iterator(); iterator.hasNext();)
        {
            BeanDefinitionHolder holder = (BeanDefinitionHolder)iterator.next();
            BeanDefinition bd = holder.getBeanDefinition();
            try
            {
                if((bd instanceof AbstractBeanDefinition) && ((AbstractBeanDefinition)bd).hasBeanClass())
                    parse(((AbstractBeanDefinition)bd).getBeanClass(), holder.getBeanName());
                else
                    parse(bd.getBeanClassName(), holder.getBeanName());
            }
        }
    }
 protected final void parse(String className, String beanName)
        throws IOException
    {
        MetadataReader reader = metadataReaderFactory.getMetadataReader(className);
        processConfigurationClass(new ConfigurationClass(reader, beanName));
    }
}

//扫描组件注解配置解析器
class ComponentScanAnnotationParser
{
   public ComponentScanAnnotationParser(ResourceLoader resourceLoader, Environment environment, BeanNameGenerator beanNameGenerator, BeanDefinitionRegistry registry)
    {
        this.resourceLoader = resourceLoader;
        this.environment = environment;
        this.beanNameGenerator = beanNameGenerator;
        this.registry = registry;
    }
    //解析注解配置
     public Set parse(AnnotationAttributes componentScan, String declaringClass)
    {
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry, componentScan.getBoolean("useDefaultFilters"));
        Assert.notNull(environment, "Environment must not be null");
        scanner.setEnvironment(environment);
        Assert.notNull(resourceLoader, "ResourceLoader must not be null");
        scanner.setResourceLoader(resourceLoader);
        Class generatorClass = componentScan.getClass("nameGenerator");
        boolean useInheritedGenerator = org/springframework/beans/factory/support/BeanNameGenerator.equals(generatorClass);
        scanner.setBeanNameGenerator(useInheritedGenerator ? beanNameGenerator : (BeanNameGenerator)BeanUtils.instantiateClass(generatorClass));
        ScopedProxyMode scopedProxyMode = (ScopedProxyMode)componentScan.getEnum("scopedProxy");
        if(scopedProxyMode != ScopedProxyMode.DEFAULT)
        {
            scanner.setScopedProxyMode(scopedProxyMode);
        } else
        {
            Class resolverClass = componentScan.getClass("scopeResolver");
            scanner.setScopeMetadataResolver((ScopeMetadataResolver)BeanUtils.instantiateClass(resolverClass));
        }
        //包含注解类
        AnnotationAttributes aannotationattributes[] = componentScan.getAnnotationArray("includeFilters");
        int i = aannotationattributes.length;
        for(int j = 0; j < i; j++)
        {
            AnnotationAttributes filter = aannotationattributes[j];
            TypeFilter typeFilter;
            for(Iterator iterator = typeFiltersFor(filter).iterator(); iterator.hasNext(); scanner.addIncludeFilter(typeFilter))
                typeFilter = (TypeFilter)iterator.next();

        }
        //剔除注解类
        aannotationattributes = componentScan.getAnnotationArray("excludeFilters");
        i = aannotationattributes.length;
        for(int k = 0; k < i; k++)
        {
            AnnotationAttributes filter = aannotationattributes[k];
            TypeFilter typeFilter;
            for(Iterator iterator1 = typeFiltersFor(filter).iterator(); iterator1.hasNext(); scanner.addExcludeFilter(typeFilter))
                typeFilter = (TypeFilter)iterator1.next();

        }
        List basePackages = new ArrayList();
        Object aobj[] = componentScan.getStringArray("value");
        int l = aobj.length;
        for(int i1 = 0; i1 < l; i1++)
        {
            String pkg = aobj[i1];
            if(StringUtils.hasText(pkg))
                basePackages.add(pkg);
        }
        aobj = componentScan.getStringArray("basePackages");
        l = aobj.length;
        for(int j1 = 0; j1 < l; j1++)
        {
            String pkg = aobj[j1];
            if(StringUtils.hasText(pkg))
                basePackages.add(pkg);
        }
        aobj = componentScan.getClassArray("basePackageClasses");
        l = aobj.length;
        for(int k1 = 0; k1 < l; k1++)
        {
            Class clazz = aobj[k1];
            basePackages.add(ClassUtils.getPackageName(clazz));
        }
        //扫描基本包
        return scanner.doScan(StringUtils.toStringArray(basePackages));
    }
}

//ClassPathBeanDefinitionScanner,bean定义扫描
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider
{
 protected transient Set doScan(String basePackages[])
    {
        Assert.notEmpty(basePackages, "At least one base package must be specified");
        Set beanDefinitions = new LinkedHashSet();
        String as[] = basePackages;
        int i = as.length;
label0:
        for(int j = 0; j < i; j++)
        {
            String basePackage = as[j];
            Set candidates = findCandidateComponents(basePackage);
            Iterator iterator = candidates.iterator();
            do
            {
                if(!iterator.hasNext())
                    continue label0;
                BeanDefinition candidate = (BeanDefinition)iterator.next();
                ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(candidate);
		//设置bean作用域
                candidate.setScope(scopeMetadata.getScopeName());
                String beanName = beanNameGenerator.generateBeanName(candidate, registry);
                if(candidate instanceof AbstractBeanDefinition)
		     //bean自动注入auotwired处理
                    postProcessBeanDefinition((AbstractBeanDefinition)candidate, beanName);
                if(candidate instanceof AnnotatedBeanDefinition)
		   //处理lazy等注解
                    AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition)candidate);
                if(checkCandidate(beanName, candidate))
                {
                    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, registry);
                    beanDefinitions.add(definitionHolder);
                    registerBeanDefinition(definitionHolder, registry);
                }
            } while(true);
        }

        return beanDefinitions;
    }
    //bean自动注入@auotwired处理
     protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName)
    {
        beanDefinition.applyDefaults(beanDefinitionDefaults);
        if(autowireCandidatePatterns != null)
            beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(autowireCandidatePatterns, beanName));
    }
}

//Servlet上下文监听器
public interface ServletContextListener
    extends EventListener
{
    public abstract void contextInitialized(ServletContextEvent servletcontextevent);
    public abstract void contextDestroyed(ServletContextEvent servletcontextevent);
}

//上下文配置文件资源
public class ClassPathResource extends AbstractFileResolvingResource
{ 
   //构遭上下文配置文件资源
public ClassPathResource(String path, ClassLoader classLoader)
    {
        Assert.notNull(path, "Path must not be null");
        String pathToUse = StringUtils.cleanPath(path);
        if(pathToUse.startsWith("/"))
            pathToUse = pathToUse.substring(1);
        this.path = pathToUse;
        this.classLoader = classLoader == null ? ClassUtils.getDefaultClassLoader() : classLoader;
    }
    //解决上下文配置文件URL
    protected URL resolveURL()
    {
        if(clazz != null)
            return clazz.getResource(path);
        if(classLoader != null)
            return classLoader.getResource(path);
        else
            return ClassLoader.getSystemResource(path);
    }
    //获取上下文配置文件输入流
    public InputStream getInputStream()
        throws IOException
    {
        InputStream is;
        if(clazz != null)
            is = clazz.getResourceAsStream(path);
        else
        if(classLoader != null)
            is = classLoader.getResourceAsStream(path);
        else
            is = ClassLoader.getSystemResourceAsStream(path);
        if(is == null)
            throw new FileNotFoundException((new StringBuilder()).append(getDescription()).append(" cannot be opened because it does not exist").toString());
        else
            return is;
    }
   //获取上下文配置文件URL
    public URL getURL()
        throws IOException
    {
        URL url = resolveURL();
        if(url == null)
            throw new FileNotFoundException((new StringBuilder()).append(getDescription()).append(" cannot be resolved to URL because it does not exist").toString());
        else
            return url;
    }
   //创建相对路径上下文配置文件资源
    public Resource createRelative(String relativePath)
    {
        String pathToUse = StringUtils.applyRelativePath(path, relativePath);
        return new ClassPathResource(pathToUse, classLoader, clazz);
    }
    //获取配置文件名
    public String getFilename()
    {
        return StringUtils.getFilename(path);
    }
    private final String path;//路径
    private ClassLoader classLoader;//上下文加载类
    private Class clazz;
}

//属性配置文件加载工具
public abstract class PropertiesLoaderUtils
{
  //加载配置文件
 public static Properties loadProperties(Resource resource)
        throws IOException
    {
        Properties props = new Properties();
        fillProperties(props, resource);
        return props;
    }
    //填充配置属性
    public static void fillProperties(Properties props, Resource resource)
        throws IOException
    {
        InputStream is = resource.getInputStream();
        String filename = resource.getFilename();
        if(filename != null && filename.endsWith(".xml"))
            props.loadFromXML(is);
        else
            props.load(is);
        is.close();
        is.close();
    }
 private static final String XML_FILE_EXTENSION = ".xml";
}

//Properties
public class Properties extends Hashtable
{
   //从XML文件输入流加载配置文件
   public synchronized void loadFromXML(InputStream inputstream)
        throws IOException, InvalidPropertiesFormatException
    {
        if(inputstream == null)
        {
            throw new NullPointerException();
        } else
        {
            XMLUtils.load(this, inputstream);
            inputstream.close();
            return;
        }
    }
}

//ServletContextEvent
public class ServletContextEvent extends EventObject
{
    public ServletContextEvent(ServletContext source)
    {
        super(source);
    }
    public ServletContext getServletContext()
    {
        return (ServletContext)super.getSource();
    }
}

//ApplicationContext
public interface ApplicationContext
    extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver
{
    public abstract String getId();
    public abstract String getApplicationName();
    public abstract String getDisplayName();
    public abstract long getStartupDate();
    public abstract ApplicationContext getParent();
    public abstract AutowireCapableBeanFactory getAutowireCapableBeanFactory()
        throws IllegalStateException;
}

//WebApplicationContext
public interface WebApplicationContext
    extends ApplicationContext
{
    public abstract ServletContext getServletContext();
    public static final String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = (new StringBuilder()).append(org/springframework/web/context/WebApplicationContext.getName()).append(".ROOT").toString();
    public static final String SCOPE_REQUEST = "request";
    public static final String SCOPE_SESSION = "session";
    public static final String SCOPE_GLOBAL_SESSION = "globalSession";
    public static final String SCOPE_APPLICATION = "application";
    public static final String SERVLET_CONTEXT_BEAN_NAME = "servletContext";
    public static final String CONTEXT_PARAMETERS_BEAN_NAME = "contextParameters";
    public static final String CONTEXT_ATTRIBUTES_BEAN_NAME = "contextAttributes";
}

//ConfigurableWebApplicationContext
public interface ConfigurableWebApplicationContext
    extends WebApplicationContext, ConfigurableApplicationContext
{
    public abstract void setServletContext(ServletContext servletcontext);
    public abstract void setServletConfig(ServletConfig servletconfig);
    public abstract ServletConfig getServletConfig();
    public abstract void setNamespace(String s);
    public abstract String getNamespace();
    public abstract void setConfigLocation(String s);
    public abstract void setConfigLocations(String as[]);
    public abstract String[] getConfigLocations();
    public static final String APPLICATION_CONTEXT_ID_PREFIX = (new StringBuilder()).append(org/springframework/web/context/WebApplicationContext.getName()).append(":").toString();
    public static final String SERVLET_CONFIG_BEAN_NAME = "servletConfig";

}

//StandardServletEnvironment
public class StandardServletEnvironment extends StandardEnvironment
    implements ConfigurableWebEnvironment
{
    public void initPropertySources(ServletContext servletContext, ServletConfig servletConfig)
    {
        //初始化ServletPropertySources
        WebApplicationContextUtils.initServletPropertySources(getPropertySources(), servletContext, servletConfig);
    }

    public static final String SERVLET_CONTEXT_PROPERTY_SOURCE_NAME = "servletContextInitParams";
    public static final String SERVLET_CONFIG_PROPERTY_SOURCE_NAME = "servletConfigInitParams";
    public static final String JNDI_PROPERTY_SOURCE_NAME = "jndiProperties";
}

//WebApplicationContext工具类
public abstract class WebApplicationContextUtils
{
  //初始化servletContextInitParams
  public static void initServletPropertySources(MutablePropertySources propertySources, ServletContext servletContext, ServletConfig servletConfig)
    {
        Assert.notNull(propertySources, "propertySources must not be null");
        if(servletContext != null && propertySources.contains("servletContextInitParams") && (propertySources.get("servletContextInitParams") instanceof org.springframework.core.env.PropertySource.StubPropertySource))
            propertySources.replace("servletContextInitParams", new ServletContextPropertySource("servletContextInitParams", servletContext));
        if(servletConfig != null && propertySources.contains("servletConfigInitParams") && (propertySources.get("servletConfigInitParams") instanceof org.springframework.core.env.PropertySource.StubPropertySource))
            propertySources.replace("servletConfigInitParams", new ServletConfigPropertySource("servletConfigInitParams", servletConfig));
    }
}

//ApplicationContextInitializer
public interface ApplicationContextInitializer
{
    public abstract void initialize(ConfigurableApplicationContext configurableapplicationcontext);
}

//bean工具类
public abstract class BeanUtils
{
  //初始化Class
  public static Object instantiateClass(Class clazz)
        throws BeanInstantiationException
    {
        Assert.notNull(clazz, "Class must not be null");
        if(clazz.isInterface())
            throw new BeanInstantiationException(clazz, "Specified class is an interface");
        return instantiateClass(clazz.getDeclaredConstructor(new Class[0]), new Object[0]);
        NoSuchMethodException ex;
        ex;
        throw new BeanInstantiationException(clazz, "No default constructor found", ex);
    }
    //根据构造函数初始化Object
     public static transient Object instantiateClass(Constructor ctor, Object args[])
        throws BeanInstantiationException
    {
        Assert.notNull(ctor, "Constructor must not be null");
        ReflectionUtils.makeAccessible(ctor);
        return ctor.newInstance(args);
        InstantiationException ex;
        ex;
        throw new BeanInstantiationException(ctor.getDeclaringClass(), "Is it an abstract class?", ex);
        ex;
        throw new BeanInstantiationException(ctor.getDeclaringClass(), "Is the constructor accessible?", ex);
        ex;
        throw new BeanInstantiationException(ctor.getDeclaringClass(), "Illegal arguments for constructor", ex);
        ex;
        throw new BeanInstantiationException(ctor.getDeclaringClass(), "Constructor threw exception", ex.getTargetException());
    }
}

总结:
Spring上下文加载监听,在静态语句块中加载配置文件contextConfigLocation,
然后初始化ServletContext,以便spring容器可以直接访问web容器上下文,注册bean后置处理器,构造bean,初始化消息源,监听器;在构造bean的过程中通过ConfigurationClassParser来解析bean,处理注解,IOC等。

猜你喜欢

转载自donald-draper.iteye.com/blog/2324926
今日推荐