zoukankan      html  css  js  c++  java
  • Spring父容器与子容器

    在使用spring+springMVC的web工程中,我们一般会在web.xml中做如下配置:

        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:application.xml</param-value>
        </context-param>
    
        <!-- spring context listener -->
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    
        <!-- spring mvc dispatcher servlet -->
        <servlet>
            <servlet-name>spring</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:spring-servlet.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>spring</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>

    这样就会产生两个spring容器,一个父容器,一个子容器。

    父容器Root WebApplicationContext由ContextLoaderListener加载
    子容器WebApplicationContext for namespace 'spring-servlet'由DispatcherServlet加载('spring-servlet'子容器的contextConfigLocation,web.xml中配置的)
    从容器里面getBean的时候,先从本容器取,如果取不到再从父容器取

    原码跟踪得到如下结果:

    ContextLoaderListener:
    beanFactory : org.springframework.beans.factory.support.DefaultListableBeanFactory@501af69e: defining beans [commonService,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,propertyConfigurer,messageSource,exceptionHandler,compositeFilter,dataSource,sqlSessionFactory,transactionManager,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,org.mybatis.spring.mapper.MapperScannerConfigurer#0,tokenClient,formTokenManager,formTokenAspect,formTokenPointCut,org.springframework.aop.aspectj.AspectJPointcutAdvisor#0,responseAspect,responsePointCut,org.springframework.aop.aspectj.AspectJPointcutAdvisor#1,multiViewResolver,excelView]; root of factory hierarchy

    applicationContext:(对象地址:6be04fe1,父容器:null)
    (org.springframework.web.context.support.XmlWebApplicationContext@6be04fe1) Root WebApplicationContext: startup date [Thu Feb 16 09:42:54 CST 2017]; root of context hierarchy
    contextId : org.springframework.web.context.WebApplicationContext:


    beanFactory.registerResolvableDependency(ApplicationContext.class, this);将父容器(根容器)注册到父容器的beanFactory中

    DispatcherServlet:
    ServletContext : org.apache.catalina.core.ApplicationContextFacade@78d9af50
    applicationContext : ( 对象地址:8323ee8,父容器:ContextLoaderListener加载的 applicationContext,即 Root WebApplicationContext)
    (org.springframework.web.context.support.XmlWebApplicationContext@8323ee8) WebApplicationContext for namespace 'spring-servlet': startup date [Thu Jan 01 08:00:00 CST 1970]; parent: Root WebApplicationContext
    contextId : org.springframework.web.context.WebApplicationContext:/spring

    beanFactory.registerResolvableDependency(ApplicationContext.class, this); 将子容器注册到子容器的beanFactory中

    父容器的ListableBeanFactory中注册的bean:(由ContextLoadListener初始化的容器)

    (java.lang.String[]) [commonService
    initService
    pageService
    org.springframework.context.annotation.internalConfigurationAnnotationProcessor
    org.springframework.context.annotation.internalAutowiredAnnotationProcessor
    org.springframework.context.annotation.internalRequiredAnnotationProcessor
    org.springframework.context.annotation.internalCommonAnnotationProcessor
    propertyConfigurer
    messageSource
    exceptionHandler
    compositeFilter
    dataSource
    sqlSessionFactory
    transactionManager
    org.springframework.aop.config.internalAutoProxyCreator
    org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0
    org.springframework.transaction.interceptor.TransactionInterceptor#0
    org.springframework.transaction.config.internalTransactionAdvisor
    org.mybatis.spring.mapper.MapperScannerConfigurer#0
    tokenClient
    formTokenManager
    formTokenAspect
    formTokenPointCut
    org.springframework.aop.aspectj.AspectJPointcutAdvisor#0
    responseAspect
    responsePointCut
    org.springframework.aop.aspectj.AspectJPointcutAdvisor#1
    multiViewResolver
    excelView
    org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor
    org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor
    ICommonDao
    IPageDao]

    子容器的ListableBeanFactory中注册的bean:(由DispatcherServlet初始化的容器)

    (java.lang.String[]) [baseTestController
    captchaController
    errorPageTestController
    excelExportController
    exceptionHandlerTestController
    paramProcessController
    tokenTestController
    validatorTestController
    org.springframework.context.annotation.internalConfigurationAnnotationProcessor
    org.springframework.context.annotation.internalAutowiredAnnotationProcessor
    org.springframework.context.annotation.internalRequiredAnnotationProcessor
    org.springframework.context.annotation.internalCommonAnnotationProcessor
    org.springframework.aop.config.internalAutoProxyCreator
    mvcContentNegotiationManager
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0
    org.springframework.format.support.FormattingConversionServiceFactoryBean#0
    org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean#0
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#0
    mvcUriComponentsContributor
    org.springframework.web.servlet.handler.MappedInterceptor#0
    org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0
    org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver#0
    org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver#0
    org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
    org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter
    org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
    org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler#0
    org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#0
    org.springframework.web.servlet.view.InternalResourceViewResolver#0]

    补充:bean中如果依赖注入了ApplicationContext,那么这个bean中注入的容器为持有这个bean的容器

    web工程,web.xml配置如上
    application.xml加载除了Controller之外的bean

    <!-- 加载@Component, @Service, @Repository -->
        <context:component-scan base-package="com.cn.kvn.usage">
            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
        </context:component-scan>
    View Code

    spring-servlet.xml加载Controller bean

    <!-- 加载@Controller -->
        <context:component-scan base-package="com.cn.kvn.usage.controller" use-default-filters="false">
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
        </context:component-scan>
    View Code

    那么在Controller bean中注入ApplicationContext拿到的是子容器,而在Service bean中注入ApplicationContext拿到的是父容器

    @Controller
    @RequestMapping("/base")
    public class BaseTestController {
        
        @Resource
        ApplicationContext applicationContext;
        
        ......
    }
    
    
    @Service
    public class CommonService implements ICommonService{
    
        @Resource
        ApplicationContext applicationContext;
        
        .......
    }

    断点跟踪,在Display窗口中打出的信息如下:

    this
    (org.springframework.web.context.support.XmlWebApplicationContext) Root WebApplicationContext: startup date [Thu Feb 16 13:50:53 CST 2017]; root of context hierarchy

    org.springframework.util.ObjectUtils.getIdentityHexString(this)
    (java.lang.String) 11667308 // 父容器的地址

    this
    (org.springframework.web.context.support.XmlWebApplicationContext) WebApplicationContext for namespace 'spring-servlet': startup date [Thu Feb 16 13:53:47 CST 2017]; parent: Root WebApplicationContext

    org.springframework.util.ObjectUtils.getIdentityHexString(this)
    (java.lang.String) 3be4f169 // 子容器的地址

    applicationContext
    (org.springframework.web.context.support.XmlWebApplicationContext) WebApplicationContext for namespace 'spring-servlet': startup date [Thu Feb 16 13:53:47 CST 2017]; parent: Root WebApplicationContext
    org.springframework.util.ObjectUtils.getIdentityHexString(applicationContext)
    (java.lang.String) 3be4f169 // Controller 中注入的ApplicationContext

    applicationContext
    (org.springframework.web.context.support.XmlWebApplicationContext) Root WebApplicationContext: startup date [Thu Feb 16 13:50:53 CST 2017]; root of context hierarchy
    org.springframework.util.ObjectUtils.getIdentityHexString(applicationContext)
    (java.lang.String) 11667308 // Service 中注入的ApplicationContext

  • 相关阅读:
    leetcode 131. Palindrome Partitioning
    leetcode 526. Beautiful Arrangement
    poj 1852 Ants
    leetcode 1219. Path with Maximum Gold
    leetcode 66. Plus One
    leetcode 43. Multiply Strings
    pytorch中torch.narrow()函数
    pytorch中的torch.repeat()函数与numpy.tile()
    leetcode 1051. Height Checker
    leetcode 561. Array Partition I
  • 原文地址:https://www.cnblogs.com/kevin-yuan/p/6404702.html
Copyright © 2011-2022 走看看