美文网首页
MyBatis + spring + springMVC 之S

MyBatis + spring + springMVC 之S

作者: Butif_D | 来源:发表于2018-08-31 18:20 被阅读0次

    spring 的父子容器的关系;规格和继承一样! 父容器不能使用子容器的bean,子容器可以!
    WHY:包扫描BUG!引出spring父子容器的问题。
    在spring核心概念中【容器】是核心思想,它是用来管理bean生命周期的,在一个项目中存在多个容器时,就会有这个层级关系;
    SSM中常用的是spring+springMVC配置文件;

    【可以用配置:<context:component-scan base-package="**" /> 批量注册,且不需要分开注册,
    Spring提供的参考手册中我们得知该配置的功能是扫描配置的base-package包下的所有使用了@Component注解的类,
    并且将它们自动注册到容器中,
    同时也扫描@Controller,@Service,@Respository这三个注解,因为他们是继承自@Component。
    <context:component-scan base-package="~~" />必须在spring中配置并且必须加上下面配置;因为springMVC默认不会去找父容器中的Controller】

        <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
           <property name="detectHandlerMethodsInAncestorContexts">
               <value>true</value>
           </property>
        </bean>  {最下面有  解  }
    

    {此配置 上面配置默认打开}
    <context:annotation-config/>配置代表的是:默认声明注解:@Required , @Autowired , @PostConstrut
    @PersistenceContext , @Resource , @PreDestroy

    <mvc:annotation-driven />
    这个是SpringMVC必须要配置的,它声明了@RequestMapping、@RequestBody、@ResponseBody等。
    并且,该配置默认加载很多的参数绑定方法,比如json转换解析器等
    @RequestMapping :请求及请求路径映射到具体方法上
    @RequestBody :页面JOSN转成java对象
    @ResponseBody :后端Java对象转JSON数据
    等价的配置

        <!--配置注解控制器映射器,它是SpringMVC中用来将Request请求URL到映射到具体Controller-->
        <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
        <!--配置注解控制器映射器,它是SpringMVC中用来将具体请求映射到具体方法-->
        <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
    
        <!--配置注解控制器映射器,它是SpringMVC中用来将Request请求URL到映射到具体Controller-->
        <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
        <!--配置注解控制器映射器,它是SpringMVC中用来将具体请求映射到具体方法-->
        <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
    

    这个不是很清楚【**】
    下面我们来查看具体原因,翻看源码,从SpringMVC的DispatcherServlet开始往下找,
    我们发现SpringMVC初始化时,会寻找SpringMVC容器中的所有使用了@Controller注解的Bean,
    来确定其是否是一个handler。
    1,2两步的配置使得当前springMVC容器中并没有注册带有@Controller注解的Bean,
    而是把所有带有@Controller注解的Bean都注册在Spring这个父容器中了,
    所以springMVC找不到处理器,不能进行跳转。核心源码如下:

    protected void initHandlerMethods() {
      if (logger.isDebugEnabled()) {
        logger.debug("Looking for request mappings in application context: " + getApplicationContext());
      }
      String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ?
            BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :
           getApplicationContext().getBeanNamesForType(Object.class));
      for (String beanName : beanNames) {
        if (isHandler(getApplicationContext().getType(beanName))){
          detectHandlerMethods(beanName);
        }
      }
      handlerMethodsInitialized(getHandlerMethods());
    }
    

    在方法isHandler中会判断当前bean的注解是否是controller

    protected boolean isHandler(Class<?> beanType) {
      return AnnotationUtils.findAnnotation(beanType, Controller.class) != null;
    }
    

    在initHandlerMethod()方法中的detectHandlerMethodsInAncestorContexts默认是不包括父容器的;所以解决之前的问题可以在
    springMVC的配置中加

    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
       <property name="detectHandlerMethodsInAncestorContexts">
           <value>true</value>
       </property>
    </bean>  
    

    SpringMVC容器会把service、dao层的bean重新加载,
    从而造成新加载的bean覆盖了老的bean,
    但事务的AOP代理没有配置在spring-mvc.xml配置文件中,造成事务失效。
    解决办法是:在spring-mvc.xml配置文件中的context:component-scan标签中
    使用use-default-filters=“false”禁用掉默认的行为。

    <context:component-scan base-package="com.hafiz.www" use-default-filters="false">
       <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>
    

    mybatis+spring+springMVC小整合:
    注意:spring配置和springMVC配置存在的父子容器的关系;spring[父]:不能使用springMVC[子]容器的bean;相反 子>>父
    介意: spring:扫描service
    bean映射器配置器MapperScannerConfigurer -->basePackage扫描dao ;
    springMVC:扫描Controller ;

    相关文章

      网友评论

          本文标题:MyBatis + spring + springMVC 之S

          本文链接:https://www.haomeiwen.com/subject/oxjewftx.html