springMVC入门

1. 简介

​ SpringMVC 是一种基于 Java 的实现 MVC 设计模式的轻量级 Web 框架,属于SpringFrameWork 的 后续产品,已经融合在 Spring Web Flow 中。 SpringMVC 已经成为目前最主流的MVC框架之一,并且随着Spring3.0 的发布,全面超越 Struts2, 成为最优秀的 MVC 框架。它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持 RESTful 编程风格的请求。

​ SpringMVC的框架就是封装了原来Servlet中的共有行为;例如:参数封装,视图转发等。

2. 入门案例

1、导包

<!--springMVC坐标-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.1.5.RELEASE</version>
</dependency>

2、配置servlet

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

理解:

DispatcherServlet类是SpringMVC提供的一个Servlet。其内部会加载Springmvc配置并构建容器。设置它匹配所有请求,拿到请求后它会在容器中找对应的实例来处理。如此一来我们就不需要编写servlet了,只需要编写bean然后指定用于处理那个请求就可以了。

contextConfigLocation初始化参数则是指定springmvc配置文件的位置。

servlet相关知识
<load-on-startup> 当其为负数或者不指定时,servlet在首次被访问时加载,当其为0或者正整数时,Tomcat启动时servlet就被加载。其值越小越先被加载。

<url-pattern> 当值为 / 时,表示匹配除 *.jsp之外的所有请求(目前只知道jsp是个例外),而 /* 则表示匹配所有请求。设置为/* 时的问题:controller转发到jsp或其他页面时又会被次controller拦截,就会出现404。 ==设置为 / 时:==jsp页面可以正常访问,但HTML等资源的访问依然会被拦截。

3、编写bean作为处理器

@Controller
public class UserController {
    @RequestMapping("/quick")
    public String quick() {
        System.out.println("quick running.....");
        return "/WEB-INF/pages/success.jsp";
    }
}

@RequestMapping注解指定匹配请求的路径。

4、编写spring核心配置文件

SpringMVC中配置文件一般命名为spring-mvc.xml,在其中开启注解扫描即可。

2.1 Tomcat执行流程

image-20210220140714491

2.2 springmvc的执行流程

即DispatcherServlet的执行流程:

image-20210220140855776

1. 用户发送请求至前端控制器DispatcherServlet。
2. DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3. 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4. DispatcherServlet调用HandlerAdapter处理器适配器。
5. HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
6. Controller执行完成返回ModelAndView。
7. HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
9. ViewReslover解析后返回具体View。
10. DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11. DispatcherServlet将渲染后的视图响应响应用户。

2.3 springMVC 组件

1. 前端控制器:DispatcherServlet
用户请求到达前端控制器,它就相当于 MVC 模式中的 C,DispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,DispatcherServlet 的存在降低了组件之间的耦合性。
2. 处理器映射器:HandlerMapping
HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
3. 处理器适配器:HandlerAdapter
通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
4. 处理器:Handler【**开发者编写**】
它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到Handler。由Handler 对具体的用户请求进行处理。
5. 视图解析器:ViewResolver
View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名,即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。
6. 视图:View 【**开发者编写**】
SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。最常用的视图就是 jsp。一般情况下需要通过

三大组件:处理器映射器、处理器适配器、视图解析器

image-20210222163414030

在spring配置文件中配置 组件

<!--处理器映射器和处理器适配器功能增强-->
<mvc:annotation-driven/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/pages/"></property>
    <property name="suffix" value=".jsp"></property>
</bean>

不配置会使用默认的组件,<mvc:annotation-driven/>同时配置映射器和适配器,直观用途为增加了对JSON的支持

new一个InternalResourceViewResolver实例放到容器中,就会使用其作为视图适配器,主要用用途是可以通过prefix和suffix设置前后缀,这样在控制器只需返回逻辑视图名即可。注意:prefix要以 / 开头,否则会以访问的路径的父路径为当前路径进行拼接。

2.4 springmvc配置文件 & @RequestMapping

与spring整合时,springmvc的容器只是作为子容器,注意这不是同一个容器,所以一般springmvc只会管理Controller层的Bean,而由spring管理Service层DAO层的Bean。

@RequestMapping使用

1、此注解可以使用在类上或者方法上,使用在类上为一级访问目录,方法上的为二级访问路径,匹配时两者会结合。

​ 老师说路径都要以 / 开头,但经测试好像 加不加 / 效果一样,但还是都以 / 开头吧,一来保险,二来也顺眼。

2、路径的配置使用的是此注解的value属性[path属性也是一样的],此注解另外还常用method属性和params属性,前者指定访问方式,后者则是指定访问时必须携带的参数。

@RequestMapping(value = "/hello",method = RequestMethod.GET,params = {"aa"})

此注解修饰的方法只能通过get方式访问,访问时必须携带参数 aa

3. 请求参数封装

3.1 对于普通表单数据

springmvc对请求参数的获取进行了分装,不必自行调用getParameter进行获取。

1、将请求参数作为Controllor方法的参数即可,springmvc会根据变量名与参数名进行匹配,并且进行数据类型转化。【参数接受】

2、也可以以实体类为参数,springmvc会将参数按照名称对应装入实体的属性中。【实体类接受】

3、对于复选框这样的情况,spring可以将参数值分装进数组,所以只要指定方法参数时设为数组即可。【数组接受 复选框】

3.2 对于复杂数据类型

<form action="${pageContext.request.contextPath}/user/queryParam" method="post">
    搜索关键字:
    <input type="text" name="keyword"> <br>
    user对象:
    <input type="text" name="user.id" placeholder="编号">
    <input type="text" name="user.username" placeholder="姓名"><br>
    list集合<br>
    第一个元素:
    <input type="text" name="userList[0].id" placeholder="编号">
    <input type="text" name="userList[0].username" placeholder="姓名"><br>
    第二个元素:
    <input type="text" name="userList[1].id" placeholder="编号">
    <input type="text" name="userList[1].username" placeholder="姓名"><br>
    map集合<br>
    第一个元素:
    <input type="text" name="userMap['u1'].id" placeholder="编号">
    <input type="text" name="userMap['u1'].username" placeholder="姓名"><br>
    第二个元素:
    <input type="text" name="userMap['u2'].id" placeholder="编号">
    <input type="text" name="userMap['u2'].username" placeholder="姓名"><br>
    <input type="submit" value="复杂类型">
</form>
public class QueryVo {
    private String keyword;
    private User user;
    private List<User> userList;
    private Map<String, User> userMap;
}
@RequestMapping("/queryParam")
public String queryParam(QueryVo queryVo) {
    System.out.println(queryVo);
    return "success";
}

注意,其他对象,List Map 这些复杂数据类型,只能以实体类属性的方式进行分装,不能直接出现在Controller参数中。

3.3 解决Post中文乱码

<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

记住过滤器类名CharacterEncodingFilter,以及注意指定初始化参数encoding即可。

3.4 自定义类型转换

import org.springframework.core.convert.converter.Converter;

public class DateConverter implements Converter<String,Date> {
    @Override
    public Date convert(String s) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            return sdf.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}

配置:

<mvc:annotation-driven conversion-service="conversionService" />
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="mc.converters.DateConverter"/>
        </set>
    </property>
</bean>

记忆:

1、实现Converter接口进行自定义转换器,注意接口所属的包,属于springframework并且包含多个convert

2、Convert的两个泛型是指 将什么类型转化为什么类型

3、配置转换器是,是new一个ConversionServiceFactoryBean的实例,并将 自定义类的实例 放到 其属性converters【set集合】中。

4、最后不要忘了要将new除来的ConversionServiceFactoryBean实例指定给annotation-driven才行。

3.5 参数封装相关注解

@RequestParam注解

作用位置:Controller方法的形参上。

注解属性:

​ name : 指定对应的请求参数,用于解决请求参数名必须与方法参数名同名的缺陷。

​ required : 是否必须传此参数,默认为true,当指定了defaultValue时默认为false。

​ defaultValue :若请求没有传此参数时的默认值。

@RequestHeader注解

上述参数封装只能封装请求体中携带的参数。此注解的作用在于将请求头中的数据封装进方法参数中。

作用位置:Controller方法的形参上。

public String doform2(@RequestHeader("Content-Type") String type) { . . .  }

@CookieValue注解

作用:获取分装Cookie中的数据

public String doform2(@CookieValue("JSESSIONID") String id) { . . .  }

3.6 使用servlet原生对象

如何在Controller方法中使用Servlet中常用的对象呢?如HttpServletRequest等。

直接定义这些类型的参数即可。

public String func(HttpServletRequest request, HttpServletResponse response, HttpSession session){ . . . }

4. 请求响应

4.1 响应分类

页面跳转

  1. 返回字符串逻辑视图
  2. void原始ServletAPI
  3. ModelAndView

返回数据

  1. 直接返回字符串数据
  2. 将对象或集合转为json返回

4.2 springMVC方式实现 重定向和转发

重定向和转发

使用原始API可以实现重定向和转发,但是需要植入request和response对象,还要调用方法,较为麻烦;返回逻辑视图也是一种请求转发,但是其受前后缀限制。

通过return 字符串中添加forward关键字进行转发

return "forward:/WEB-INF/pages/success.jsp";

通过return 字符串中添加redirect关键字进行转发

return "redirect:/index.jsp";

==注意:==这里以 / 开头表示应用程序根目录。原生重定向时,/ 表示网站根路径

Model参数

在控制器方法中添加Model类型参数,其作用与request的作用域相似,可通过addAttribute存入参数,在转发后获取。

若是重定向,model中添加的参数会成为二次请求的请求参数

注意

  • 添加参数的方法是 add 不同于Request
  • 好像转发后写的controller无法取出model中的值,但是model中的值在转发时会被写入request作用域中。可以使用request对象获取。

4.3 ModelAndView对象

使用ModelAndView也可以实现转发,可以自己直接new一个ModelAndView的对象,也可以作为Controller方法的参数给出。

调用其addObject(String key,Object o)方法可以将数据存入model。

调用其setViewName(String name)方法可以指定逻辑视图名。

然后,return此ModelAndView对象即可。

ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("pp","13931154861");
modelAndView.setViewName("success");
return modelAndView;

也可以直接在new对象的时候直接指定视图名。

4.4 @SessionAttributes注解

@SessionAttributes({"name"})

必须标注在Controller类上

作用:可以理解为将model中的指定属性保存到Session作用域,而一般的model中的数据则是被保存进Request作用域。

5. 开启静态资源访问

由于前端控制器的匹配路径设置为了 / ,这样可以对jsp放行,但是html的等静态资源依然会被拦截,如何使这些资源能够正常访问呢?

方式一:

<!--在springmvc配置文件中指定放行资源-->
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/css/**" location="/css/"/>
<mvc:resources mapping="/img/**" location="/img/"/>

使用标签mvc:resource 属性名: mapping location

以 / 开头,当前应用为根目录,** 表示其下所有内容,包括子目录。

方式二:

<!--在springmvc配置文件中开启DefaultServlet处理静态资源-->
<mvc:default-servlet-handler/>

记忆标签名:mvc:default-servlet-handler

原始servlet开发中,默认就是使用DefaultServlet管理静态资源的。

比较:
方式一配置较为麻烦,但是可以精准控制开放那些资源,方式二配置简单,但是会开放所有资源。


1. Ajax异步交互

Ajax请求一般返回的是JSON数据,springMVC如何处理JSON数据呢?

通过@RequestBody注解将json数据封装进一个对象或者集合中,通过@ResponseBody可以将控制器返回值转换为JSON字符串格式并返回给浏览器。

举例:

@RequestMapping("/ajaxtest")
@ResponseBody
public List<User> ajaxx(@RequestBody List<User> list){ ... }

另外还需要引入JSON解析所需的依赖:

<!--Jackson-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.8</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.8</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.0</version>
</dependency>

2. Restfull编程风格

1、简介

Restfull是一种编程风格,这种风格更适用于前后端分离的项目,REST是一种后端API的定义规范,使用该规范可以设计出更加简洁有层次感的API。

2、规范

Restful风格的请求是使用“url+请求方式”表示一次请求目的的。

如:GET方式表示读取 POST方式表示新建 PUT表示更新 DELETE表示删除

image-20210221144617462

如上,相同的url却可以表示不同的功能,

而 /{1} 这样的占位符则允许我们通过url路径传递参数

springmvc对restfull的支持

1、 @GetMapping @PostMapping @PutMapping @DeleteMapping

​ 这些注解相当于@RequestMapping添加了methen声明。可以对应的匹配各种请求,使用起来更加方便。

2、@PathVariable

​ 此注解用于获取占位符的参数值

3、@RestController

​ 由于一般Rest风格的程序为前后端分离项目,请求的返回值类型一般为JSON。@RestController注解用于替换@Controller注解,相当于@Controller和@ResponseBody的结合,是由之后Controller中的所有方法,都会将返回值转化为JSON字符串返回客户端。

4、@CrossOrigin

​ 解决跨域问题,前后端分离项目一般都不会是相同的域。

举例:

@RestController
@CrossOrigin
public class myControllor {
    @GetMapping(value = "/rest/{name}",produces = {"text/html;charset=utf-8"})
    public String restTest(@PathVariable  String name, HttpServletResponse response){
        System.out.println("路径参数为:"+name);
        return "请求的name为:"+name;
    }
}

注意

Rest只是一种编程风格,而如上这些注解时springmvc提供的功能,这些功能肯定是可用不,不论是否循循rest风格要求。

3. 文件上传

3.1 文件上传三要素

  • 表单项 type=“file”
  • 表单的提交方式 method=“POST”
  • 表单的enctype属性是多部分表单形式 enctype=“multipart/form-data"

3.2 springmvc中的文件上传

1、springmvc中的文件上传机制依赖于 FileUpload 和 Common-IO工具类。所以要先导包:

<!-- fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.2.1</version>
</dependency>
<!-- commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>1.4</version>
</dependency>

2、在容器中放一个CommonsMultipartResolver对象,并制定一些上传约束

<!--文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 设定文件上传的最大值为5MB,5*1024*1024 -->
    <property name="maxUploadSize" value="5242880"></property>
    <!-- 设定文件上传时写入内存的最大值,如果小于这个参数不会生成临时文件,默认为10240 -->
    <property name="maxInMemorySize" value="40960"></property>
</bean>

记住类名:CommonsMultipartResolver

3、控制器中接受上传文件

使用MultipartFile类型的参数可以接受上传的文件对象。同样参数名与file表单的name保持一致。若上传的文件有多个,则使用MultipartFilep[]数组即可。

@RestController
public class myControllor {
    @PostMapping(value = "/fileupload",produces = {"text/html;charset=utf-8"})
    public String restTest(String name, MultipartFile[] files) throws IOException {
        System.out.println("名字:"+name);
        for (MultipartFile file : files) {
            String fileName = file.getOriginalFilename();
            file.transferTo(new File("C:\\Users\\默尘\\Desktop\\新建文件夹",fileName));
            System.out.println("文件: "+fileName+"  上传成功!");
        }
        return "上传成功!!";
    }
}

记住使用MultipartFile对象接受就行,

getOriginalFilename()   是获取文件名
getName()  			  是获取表单项name的值,没什么用。
transferTo(File f)     可以拷贝文件
getContentType()      获取文件类型
getSize()          获取文件大小
getInputStream() 
getBytes()

方法见名知意。

4. 异常处理机制

4.1 java异常处理

image-20210221172548174

springmvc的异常处理机制要求我们,不必就地处理异常,向上抛出即可,抛出到前端控制器,前端控制器会调用异常处理器进行异常处理。

springmvc提供了默认的异常处理器,但是我们也可以通过实现HandlerExceptionResolver接口自定义异常处理器

@Component
public class MyExceptionHandler implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, Exception e) {
        ModelAndView mav = new ModelAndView("error");
        mav.addObject("err",e.getMessage());
        return mav;
    }
}

创建好异常处理器后将其放到容器中即可生效。

4.2 错误码跳转页面

将404等错误代码转发到错误显示页面。

<!--处理500异常-->
<error-page>
    <error-code>500</error-code>
    <location>/500.jsp</location>
</error-page>
<!--处理404异常-->
<error-page>
    <error-code>404</error-code>
    <location>/404.jsp</location>
</error-page>

注意:配置文件是web.xml,这是属于servlet的知识点。

location必须以 / 开头,表示应用程序根目录,可以配置WEB-INF中的页面,这里是请求转发。但是配置html也可以。

5. 拦截器 interceptor

5.1 简介

​ Spring MVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。 将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(InterceptorChain)。在访问被拦截 的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是AOP思想的具体实 现。

拦截器和过滤器区别:

image-20210221175318281

5.2 编写拦截器

1、编写拦截器

实现HandlerInterceptor接口即可。

public class interceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("到大处理器前,do something ...");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("处理器执行完,转发到视图前....");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("都执行完了,。。。。");
    }
}

image-20210221204347295

2、配置拦截器

<!--配置拦截器-->
<mvc:interceptors>
    <mvc:interceptor>
        <!--对哪些资源执行拦截操作-->
        <mvc:mapping path="/**"/>
        <bean class="com.lagou.interceptor.MyInterceptor1"/>
    </mvc:interceptor>
</mvc:interceptors>

/** 按老师将的理解是拦截所有Controller中方法的请求,但是访问JSP时,如果JSP中使用了el表达式,也会被拦截到。目前并不清楚其拦截规则到底是什么?

先记忆吧,interceptor需要xml配置,标签以mvc开头

3、拦截器链

拦截器的执行顺序与配置顺序相关。

image-20210221205411417

当某一个拦截器prehandle返回false时,就会跳转到前一个拦截器的afterCompletion执行。

如2号拦截器的prehandle返回了false : preHandle_1 = > => => preHandle_2 = > => => afterCompletion_1

如3号拦截器的prehandle返回了false : preHandle_1 = > => => preHandle_2 = > => => preHandle_3 = > => => afterCompletion_2 = > => => afterCompletion_1


1. spring整合Mybatis

**第一步:**导入整合JAR包

<!--mybatis整合spring坐标-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.1</version>
</dependency>
<!--JDBCTemplate-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.1.5.RELEASE</version>
</dependency>

理解:

要实现Mybatis与Spring整合就是要做到可以通过注入获取到mapper实例对象。单纯使用Mybatis时我们是通过SqlSession的getMapper手动获取Mapper实例的。现在要实现自动注入,那首先是要把mapper实例放进容器中,mybatis-spring帮助我们扫描mapper包,为其中的每个接口构建实例存入容器。

疑问:

1、为什么要依赖于springJDBC?

**第二步:**编写配置

<bean class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="typeAliasesPackage" value="mc.study.entity"/>
    <property name="environment" value="sqlMapConfig.xml"/>
</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="mc.study.mapper"/>
</bean>

记忆:

整合过程就是放置两个对象到容器中,SqlSessionFactoryBean中可以配置MyBatis的相关信息,相当于替换了原来Mybatis的核心配置文件,MapperScannerConfigurer中则是指明要在哪个包下描mapper接口。

注意

  • dataSource 必须要配置。

疑问:

1、为什么DataSource是必须的?纯Mybatis可以使用其他数据源吗?

2、放两个对象进去有什么用?整合后Mapper代理实例的创建是在什么时候?是单例的吗?SQLSession是单例的吗?

2. Spring整合SpringMVC

第一步:导入依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.1.5.RELEASE</version>
</dependency>

第二步:配置监听器

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:ApplicationContext.xml</param-value>
</context-param>

作用:在监听到Tomcat启动时,启动Spring容器。这样就可以在SpringMVC子容器中获取Spring容器中的实例了。

注意:注入对象时,会首先在springmvc容器中找,找不到再去父容器中找,所以配置注解扫描时要注意。

3. 各包的依赖关系

image-20210222134409405

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值