SpringMVC授课笔记1

1 XML事务(了解)

2 添加依赖

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.1</version>
</dependency>

3 去掉注解

业务类:
//@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRES_NEW)

Spring.xml
<tx:annotation-driven proxy-target-class=”true” ></tx:annotation-driven>

4 进行XML配置

| <bean id=”transactionManager” class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”>
<property name=”dataSource” ref=”dataSource”></property>
</bean><tx:advice id=”txAdvice” transaction-manager=”transactionManager”>
<tx:attributes>
<tx:method name=”update*” timeout=”5” isolation=”REPEATABLE_READ”
propagation=”REQUIRES_NEW” rollback-for=”java.lang.Exception”
/>
<tx:method name=”insert”></tx:method>
<tx:method name=”delete”></tx:method>
<tx:method name=”select*” read-only=”true”></tx:method>

<tx:method name=”*”></tx:method>
</tx:attributes>
</tx:advice>

<aop:config>

<aop:pointcut id=”poincut1” expression=”execution( com.atguigu.service..*(..))”/>

<aop:advisor advice-ref=”txAdvice” pointcut-ref=”poincut1”></aop:advisor>
</aop:config> | | —- |

5 测试

6 Spring5新特征-JSR 305注解(了解)

①JCP

JCP(Java Community Process) 是一个由SUN公司发起的,开放的国际组织。主要由Java开发者以及被授权者组成,负责Java技术规范维护,Java技术发展和更新。

②JSR

JSR 的全称是:Java Specification Request,意思是 Java 规范提案。谁向谁提案呢?任何人都可以向 JCP (Java Community Process) 提出新增一个标准化技术规范的正式请求。

③JSR305

主要功能:使用注解(例如@NonNull等等)协助开发者侦测软件缺陷。
Spring 从 5.0 版本开始支持了 JSR 305 规范中涉及到的相关注解。

SpringMVC授课笔记记1 - 图1

7 Spring5新特征:整合Junit5

8 添加依赖

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.7.0</version>
<scope>test</scope>
</dependency>

9 整合Junit5进行测试

| @SpringJUnitConfig(locations = “classpath:spring.xml”)//@ExtendWith(SpringExtension.class)
//@ContextConfiguration(value = {“classpath:spring.xml”})public class TestTransaction {

  1. @Autowired<br /> **private **EmpService **empService**;
  2. @Test<br /> **public void **testUpdateTwice() **throws **FileNotFoundException {<br /> //empService.updateTwice(1,"tomcat",2,600.0);<br /> **empService**.updateTwice(1,**"tomcat44"**,2,444.44);<br /> }<br />} |

| —- |

Junit4: org.junit.Test
Junit5: import org.junit.jupiter.api.Test;

10 Junit4和Junit5的差别

特征 JUNIT 4 JUNIT 5
声明一种测试方法 @Test @Test
在当前类中的所有测试方法之前执行 @BeforeClass @BeforeAll
在当前类中的所有测试方法之后执行 @AfterClass @AfterAll
在每个测试方法之前执行 @Before @BeforeEach
每种测试方法后执行 @After @AfterEach
禁用测试方法/类 @Ignore @Disabled
测试工厂进行动态测试 NA @TestFactory
嵌套测试 NA @Nested
标记和过滤 @Category @Tag
注册自定义扩展 NA @ExtendWith

11 总结Spring

  1. IoC
    1. 含义 控制翻转
    2. IoC容器
    3. 使用XML管理Bean(入门)
      1. Bean的生命周期
    4. 使用注解管理Bean(推荐)
      1. 第一步:注解扫描:
      2. 创建Bean的注解:@Component @Controller @Service @Reposity @Configuration
      3. 注入Bea的注解 @Value @Autowired @Qualifier
      4. 一定理解自动装配的步骤
  2. AOP
    1. AOP的底层原理:动态代理(JDK动态代理和CGLIB动态代理)
    2. AOP术语:切面Aspect、切入点pointcut、通知advice、连接点jointpoint、AOP
    3. 基于注解实现AOP
      1. 开启AOP的自动代理:
      2. LogAspect TransactionAspect
      3. 需要的注解:
        1. 切面注解 @Aspect
        2. 通知注解 @Before @After @AfterReturning @AfterThowing @Around
        3. 切入点注解 @Pointcut
    4. 基于XML实现AOP(了解)
  3. 声明式事务
    1. 声明式事务是AOP的一个经典应用
    2. 基于注解实现声明式事务
      1. 启用事务注解驱动
      2. @Transactionsal
        1. 只读事务
        2. 传播特性
        3. 隔离级别
        4. 超时时间
        5. 异常回滚和不回滚的类型
    3. 基于XML实现声明式事务(了解)

12 理解MVC架构和三层架构

SpringMVC授课笔记记1 - 图2

13 MVC架构的缺点及其解决方案

一个大缺点,三个小缺点:

![](https://cdn.nlark.com/yuque/0/2021/png/25621085/1639811365998-818c1ac9-fb7a-412f-b5b3-b6834efc4e96.png#id=d7raK&originHeight=423&originWidth=1251&originalType=binary&ratio=1&status=done&style=none)<br />但是本身也是有缺点的,比如:
  1. 每个功能都要声明对应的Servlet,Servlet数量多。即使让一个Servlet包括多个方法,也无法从根本上解决Servlet数量多的问题。

  2. 在Servlet中获取请求数据较麻烦: 需要大量的request.getParameter(“name”)。

  3. 手动的类型转换:比如int age = Integer.parseInt(request.getParameter(“age”))
  4. 响应的方式的代码其实只想声明对应的响应数据。比如:request.getRequestDispatcher(path).forward(request,response); 中最关键的还是path。

解决方案:就是SpringMVC等MVC框架
如何解决这些问题呢?比如可采用这样的方案来解决(就是SpringMVC的解决方案)。
项目只声明一个Servlet,该Servlet作为项目请求的公共入口。并且在该Servlet中根据请求地址调用对应的控制代码处理请求。
如果将控制方法(之前Servlet调用业务层、指出跳转路径等功能)全部声明在Servlet中造成代码的体系结构不清晰。
将控制方法单独声明到控制类中(Controller类)
然后Servlet中根据请求动态的调用对应的控制类中的控制方法处理请求即可。
SpringMVC授课笔记记1 - 图3

14 认识SpringMVC

SpringMVC (全称Spring Web MVC)是Spring提供给Web应用的框架设计,其实是Spring的一部分。它是一种基于Servlet的技术,提供了核心控制器和相关的组件,并制定了松散的结构,以适合各种灵活的需要。

SpringMVC 已经成为目前最主流的 MVC 框架之一。自从Spring 2.5版本发布后,由于支持注解配置,易用性有了大幅度的提高。随着 Spring3.0 的发布,全面超越 Struts2,成为最优秀的 MVC 框架。目前业界普遍选择了 SpringMVC 作为 Java EE 项目表述层开发的首选方案。

  • Spring 家族原生产品,与 IOC 容器等基础设施无缝对接
  • 表述层各细分领域需要解决的问题全方位覆盖,提供全面解决方案
  • 代码清新简洁,大幅度提升开发效率
  • 性能卓著,尤其适合现代大型、超大型互联网项目要求
  • 支持RESTful 编程风格的请求。
  • 可适配、非侵入:可以根据不同的应用场景,选择合适的控制器子类(simple型、command型、from型、wizard型、multi-action型或者自定义),而不是一个单一控制器(比如Action/ActionForm)
  • 因为模型数据不存放在特定的API里,而是放在一个Model里(Map数据结构实现,因此很容易被其他框架使用)
  • 更加简单、强大的异常处理

总之,简单易用,性能优良,同类技术中市场占有率最高,不用犹豫,就是它了。

15 创建Web项目

使用SpringMVC必须创建基于Maven的Web项目,因为Springmvc基于Servlet

16 创建Maven Java项目

17 添加Web支持

SpringMVC授课笔记记1 - 图4

SpringMVC授课笔记记1 - 图5

18 添加Web资源

Html网页<br />    图片<br />Thymeleaf网页<br />在WEB-INF下也增加了内容

19 部署并访问

Html网页:可以访问<br />    图片:也可以访问<br />Thymeleaf网页:不可以直接访问,必须经过Thymeleaf解析器解析后再跳转到页面,所以在项目中一般把Thymeleaf网页放到Web-inf/templates<br />![](https://cdn.nlark.com/yuque/0/2021/png/25621085/1639811367516-2514b486-0bdc-4c75-930c-ceecca828b05.png#id=TztHl&originHeight=454&originWidth=812&originalType=binary&ratio=1&status=done&style=none)<br />在WEB-INF下也增加了内容:不可以访问

SpringMVC授课笔记记1 - 图6

20 Hello SpringMVC基本实现

21 添加依赖

Servlet包 SpringMVC及其Spring包、Thymeleaf和Spring5整合包

<dependencies>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.1</version>
</dependency>

<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.12.RELEASE</version>
</dependency>
</dependencies>

22 Web.xml

配置总控制器。重点是其访问路径

<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>

<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>

<load-on-startup>1</load-on-startup>
</servlet><servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>

<url-pattern>.action</url-pattern>
</*servlet-mapping
>

23 配置文件springmvc.xml

springmvc的配置文件就是spring的配置文件,一个即可,结构完全相同。如果项目规模比较大,可以分拆为多个配置文件。

<context:component-scan base-package=”com.atguigu.controller”></context:component-scan>
<bean id=”viewResolver” class=”org.thymeleaf.spring5.view.ThymeleafViewResolver”>
<property name=”order” value=”1”/>
<property name=”characterEncoding” value=”UTF-8”/>
<property name=”templateEngine”>
<bean class=”org.thymeleaf.spring5.SpringTemplateEngine”>
<property name=”templateResolver”>
<bean class=”org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver”>

<property name=”prefix” value=”/WEB-INF/templates/“/>

<property name=”suffix” value=”.html”/>
<property name=”templateMode” value=”HTML5”/>
<property name=”characterEncoding” value=”UTF-8” />
</bean>
</property>
</bean>
</property>
</bean>

24 开发视图层页面

<!DOCTYPE html>
<html lang=”en” xmlns:th=”http://www.thymeleaf.org>
<head>
<meta charset=”UTF-8”>
<title>Title</title>
</head>
<body>
<a th:href=”@{/hello/login.action}”>进入</a>
</body>
</html>
<!DOCTYPE html>
<html lang=”en” xmlns:th=”http://www.thymeleaf.org>
<head>
<meta charset=”UTF-8”>
<title>Title</title>
</head>
<body>
<h3>结果页面</h3>
<p th:text=”${msg}”> </p>
</body>
</html>

25 开发分控制器

分控制器不需要继承或者实现任何其他类或者接口。
方法的返回值是String,对应转发的页面的逻辑视图,由总控制器负责添加前缀和后缀构成物理视图,进行解析渲染并返回给客户端。
方法上面使用@RequestMapping指明该方法对应的访问路径。因为目前总控制器的访问路径是*.action,所以所有Controller方法的访问路径必须以action结尾。

| @Controllerpublic class HelloController {//Handler

@RequestMapping(**"/hello/toIndex2.action"**)<br />    **public **String toIndex2(){<br />        System.**_out_**.println(**"------HelloController toIndex2-------"**);<br />        //return "/WEB/INF/templates/index2.html";<br />        **return "index2"**;<br />    }<br />    @RequestMapping(**"/hello/login.action"**)<br />    **public **String login(Model model){<br />        System.**_out_**.println(**"-------HelloController login--------"**);<br />        model.addAttribute(**"msg"**,**"login success!!"**);<br />        **return "result"**;<br />    }<br />} |

| —- |

26 部署访问

SpringMVC授课笔记记1 - 图7

注意:可以将某个分控制器的请求路径设置为/,项目启动后自动访问。前提

  1. 去掉欢迎页面,比如index.html
  2. 将总控制器的设置为/,但是设置为/后需要增加一个注解: ,可以让对分控制器的访问可以正常进行,但是静态资源无法访问了。需要再增加一个注解:,静态资源也可以正常访问。

27 Hello SpringMVC完善

28 添加日志

29 添加依赖

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>

30 添加属性文件

| <?xml version=”1.0” encoding=”UTF-8”?><configuration debug=”true”>

<appender name=”STDOUT”
class=”ch.qos.logback.core.ConsoleAppender”
>
<encoder>


<pattern>[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger] [%msg]%n</pattern>
</encoder>
</appender>

_<!-- 设置全局日志级别。日志级别按顺序分别是:DEBUG、INFO、WARN、ERROR --><br />    <!-- 指定任何一个日志级别都只打印当前级别和后面级别的日志。 --><br />    _<**root level="INFO"**><br />        _<!-- 指定打印日志的appender,这里通过“STDOUT”引用了前面配置的appender --><br />        _<**appender-ref ref="STDOUT" **/><br />    </**root**>

_<!-- 根据特殊需求指定局部日志级别 --><br />    _<**logger name="org.springframework.web.servlet.DispatcherServlet" level="DEBUG" **/>

_<!-- 指定包的日志级别--><br />    _<**logger name="com.atguigu.controller" level="DEBUG" **/><br /></**configuration**> |

| —- |

31 给分控制器添加日志

| @Controller
public class UserController {

**private **Logger **logger **= LoggerFactory._getLogger_(UserController.**class**);

@RequestMapping(**"/"**)<br />    **public **String toLogin123(){<br />        //return "/WEB-INF/templates/login.html";<br />        **logger**.debug(**"------UserController toLogin123 ----"**);<br />        //如果需要,调用业务层<br />        **return "login"**;<br />    }<br />    @RequestMapping(**"hello/login.action"**)<br />    **public **String login(Model model){<br />        //调用业务层,完成登录功能<br />        **logger**.debug(**"-----UserController login ---------"**);<br />        model.addAttribute(**"msg"**,**"登录成功"**);<br />        **return "result"**;<br />    }<br />} |

| —- |

32 测试

SpringMVC授课笔记记1 - 图8

33 使用根据简单SLF4J日志(lombok的日志注解)

@Controller
@Slf4j
public class UserController {
//private Logger logger = LoggerFactory.getLogger(UserController.class);
@RequestMapping(“/“)
public String toLogin123(){
//return “/WEB-INF/templates/login.html”;
log.debug(“———UserController toLogin123!! ——“);
//如果需要,调用业务层
return “login”;
}
@RequestMapping(“hello/login.action”)
public String login(Model model){
//调用业务层,完成登录功能
log.debug(“——-UserController login!! ————-“);
model.addAttribute(“msg”,“登录成功”);
return “result”;
}
}

SpringMVC授课笔记记1 - 图9

34 总控制器的访问路径

Web项目中的资源,可以分为:

  1. 静态资料
  2. JSP资源
  3. 对分控制器的访问

总控制器的访问路径方式3:
方式1:.action 对静态资源和JSP资源的访问不经过总控制器,曾经最流行的方式。缺点:不支持Restful风格
方式2:/
所有的请求都经过 但是JSP和静态资源不应该经过。不要这么写
方式3:/ 只有这里可以这么写。对分控制器和静态资源的访问会经过,但是对JSP的访问不会经过。优点是支持Restful风格。这是目前推荐的方式。在该方式,分控制器的路径是否写.action后缀已经不重要。但是Restful风格不建议写后缀。
缺点:静态资源也会经过,其实是没有必要的,也会出问题。
解决方案:

<mvc:annotation-driven></mvc:annotation-driven><mvc:default-servlet-handler></mvc:default-servlet-handler>

35 RequestMapping

36 作用

从注解名称上我们可以看到,@RequestMapping注解的作用就是将请求的 URL 地址和处理请求的方式关联起来,建立映射关系。

SpringMVC授课笔记记1 - 图10

37 位置

  写在类上 @RequestMapping(“/hello”)<br />  写在方法上 @RquesetMapping(“/login”) <br />最终方法的请求路径是是类上和方法上连接:/hello/login

38 使用

①精确匹配

<a th:href=”@{/hello/login.action}”>提交登录</a><br>
<a th:href=”@{/hello/to/spring/mvc}”>HelloWorld</a><br/>
@RequestMapping(“hello/login.action”)public String login(Model model){
//调用业务层,完成登录功能
log.debug(“——-UserController login!! ————-“);
model.addAttribute(“msg”,“登录成功”);
return “result”;
}@RequestMapping(“/hello/to/spring/mvc”)public String login2(Model model){
model.addAttribute(“msg”,“/hello/to/spring/mvc!!”);
log.debug(“——-UserController login2 /hello/to/spring/mvc———“);
return “result”;
}

②模糊匹配

<a th:href=”@{/hello/fruit/apple}”>@RequestMapping模糊匹配[apple]</a><br/>
<a th:href=”@{/hello/fruit/orange}”>@RequestMapping模糊匹配[orange]</a><br/>
<a th:href=”@{/hello/fruit/banana}”>@RequestMapping模糊匹配[banana]</a><br/>
@RequestMapping(“/hello/fruit/*”)public String login3(Model model){
model.addAttribute(“msg”,“/hello/fruit/*”);
log.debug(“——-UserController login3 /hello/fruit/*———“);
return “result”;
}

39 其他写法

@RequestMapping(value = “/to/spring/mvc”,method = RequestMethod.GET )
@GetMapping(“/to/spring/mvc”)
@PostMapping(“/to/spring/mvc”)

SpringMVC授课笔记记1 - 图11

40 视图控制器

如果一个分控制器的方法的作用只是页面的跳转,可以使用<mvc:view-controller>来替代。

@RequestMapping(“/“)public String toLogin123(){
//return “/WEB-INF/templates/login.html”;
log.debug(“———UserController toLogin123??——“);
//如果需要,调用业务层
return “login”;
}
<mvc:view-controller path=”/“ view-name=”login”></mvc:view-controller>