spring springmvc容器管理controller的疑惑

在soa的项目中,web层的项目不需要spring,由此根据一些资料做个总结。

Spring和SpringMVC父子容器:在一个项目中,容器不一定只有一个,Spring中可以包括多个容器,而且容器有上下层关系。Spring是父容器,SpringMVC是其子容器,并且在Spring父容器中注册的Bean对于SpringMVC容器中是可见的,而在SpringMVC容器中注册的Bean对于Spring父容器中是不可见的。

注解配置来对Bean进行批量注册:<context:component-scan base-package="com.wsc" />@Controller,@Service,@Respository这三个注解,SpringMVC相关如下配置,经过验证,这个是SpringMVC必须要配置的,因继承自@Component

<mvc:annotation-driven />SpringMVC相关配置,它声明了@RequestMapping、@RequestBody、@ResponseBody等。并且,该配置默认加载很多的参数绑定方法,比如json转换解析器等。<mvc:annotation-driven />等于之前的两个配置
<!--配置注解控制器映射器,它是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"/>

Spring和SpringMVC两个容器,它们的配置文件分别为applicationContext.xml和springmvc.xml

1.在applicationContext.xml中配置了<context:component-scan base-package=“com.wsc" />,负责所有需要注册的Bean的扫描和注册工作。

2.在springmvc.xml中配置<mvc:annotation-driven />,负责SpringMVC相关注解的使用。

有的时候启动项目我们发现SpringMVC无法进行跳转,SpringMVC容器中的请求没有映射到具体controller中:Spring把所有带有@Controller注解的Bean都注册在Spring这个父容器中了,所以springMVC找不到处理器,不能进行跳转。

官方建议我们就可以很好把不同类型的Bean分配到不同的容器中进行管理

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/applicationContext.xml</param-value>
</context-param>

<listener>
        <description>spring监听器</description>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- spring mvc 前端控制器servlet -->
    <servlet>
        <description>spring mvc servlet</description>
        <servlet-name>springMvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <description>配置spring mvc加载的配置文件(配置处理器映射器、适配器等等)</description>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/springmvc.xml</param-value>
        </init-param>
        <!-- 1容器启动时初始化该servlete, 0第一次访问的时候初始化该servlet -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springMvc</servlet-name>
        <!-- 可行: /、*.xxx、/xxx/* 不可行: /* (struct中可以这样配置,原因是struct和springmvc的入口不一样,struct入口是Filter,springmvc入口是servlet,在servlet中“/”就代表全部了) -->
        <url-pattern>/rest/*</url-pattern>
        <!-- <url-pattern>*.do</url-pattern> -->
    </servlet-mapping>

ContextLoaderListener监听器是装载Spring框架本身的bean上下文(如Service和DAO层等),DispatcherServlet是装载SpringMVC的上下文。

applicationContext.xml:<context:component-scan base-package="com.taotao" />

springmvc.xml:<!-- 扫描Controller --> <context:component-scan base-package="com.taotao.manager.controller" />

Spring容器(上下文)创建完成之后,当初始化springMVC容器的时候,就会将之前初始化的Spring容器设置为它的父容器。如果项目中没有初始化Spring父容器,springMVC也会初始化一个默认的父容器。

注意:上面的配置中springMVC子容器所扫描的包只能限定在controller包,如果将Spring容器和springMVC容器所扫描的包都配置成全部的,就会造成在子容器和父容器都有全部的自定义beans。当子类容器中装载了Service和DAO,控制层就会使用子类容器所装载的bean去执行。但是这里面的service是没有事务等功能的(没有Spring框架的配置),只是普通的bean,因此使用起来会有不可预知的问题。

猜你喜欢

转载自blog.csdn.net/qq_41875147/article/details/81075283
今日推荐