Spring Boot是由Pivotal团队提供的全新框架
,其设计目的是用来简化Spring应用的 初始搭建以及开发过程
。该框架使用了特定的方式来进行配置
,从而使开发人员不 再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应 用开发领域(rapid application development)成为领导者。
springboot(微框架) = springmvc(控制器) + spring core(项目管理)
SSM Spring springmvc mybatis <---- SSM Spring stauts2|struts1 mybatis <— SSH Spring Struts Hibernate
创建独立的Spring应用程序
嵌入的Tomcat,无需部署WAR文件
简化Maven配置
自动配置Spring,没有XML配置
项目目录结构:
springboot 项目中必须在src/main/resources中放入application.yml(.properties)核心配置文件 名字必须为:application
springboot 项目中必须在src/main/java中所有子包之外构建全局入口类型,xxApplication,入口类一个springboot项目只能有一个
环境要求:
# 1.System Requirements
JDK18.+
MAVEN3.3 or Gradle 5.x and 6.x (4.10 is also supported but in a deprecated form)
Spring Framework 5.2.4.RELEASE
# 2.ServletContainers:
Tomcat 9.0
安装Tomcat后出现:Web server failed to start. Port 8080 was already in use.
Jetty 9.4
Undertow 2.0
# 3.开发工具
IDEA 2018版本
Eclipse 版本 17版本之后
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.2.5.RELEASEversion>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
项目中src/main/resources/application.yml
//在项目中创建指定的包结构
/*
com
+| baizhi
+| controller */
@Controller
@RequestMapping("/hello")
public class HelloController {
@RequestMapping("/hello")
@ResponseBody
public String hello(){
System.out.println("======hello world=======");
return "hello";
}
}
//在项目中如下的包结构中创建入口类 Application
SpringApplication spring应用类 作用:用来启动springboot应用。
参数一:传入入口类 类对象
参数二:main函数的参数
/*
com
+| baizhi */
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8989 (http)
com.baizhi.Application : Started Application in 2.152 seconds (JVM running for 2.611)
//说明: 出现以上日志说明启动成功
//注意: springboot的项目默认没有项目名
//访问路径: http://localhost:8080/hello/hello
server:
port: 8989 #用来指定内嵌服务器端口号
context-path: /springboot #用来指定项目的访问路径
Spring boot通常有一个名为 xxxApplication的类,入口类中有一个main方法, 在main方法中使用SpringApplication.run(xxxApplication.class,args)启动springboot应用的项目。
@RestController: 作用:用来实例化当前对象为一个控制器对象,并将类上所有方法的返回值转为json,响应给浏览器。修饰范围:用在类上。就是@Controller(实例化当前类为一个控制器) + @ResponseBody组合(用来将当前方法返回值转为json,响应给浏览器),支持RESTful访问方式,返回结果都是json字符串。(@Controller网页会改变,@RestController不会)
@SpringBootApplication 注解等价于: @EnableAutoConfiguration + @ComponentScan
@SpringBootConfiguration 标识注解,标识这是一个springboot的配置类
@EnableAutoConfiguration 自动与项目中集成的第三方技术进行集成
@ComponentScan 扫描入口类所在子包以及子包后代包中注解
@EnableAutoConfiguration 作用:开启自动配置,初始化spring环境,springmvc环境。修饰范围:只能用在类上。实际作用: 根据pom.xml文件中依赖依赖自动判断 如在第一个环境之中引入了 spring-boot-starter-web,会自动根据引入的这个依赖构建相关环境 springmvc环境 web容器环境
@ComponentScan 作用:扫描相关注解,扫描范围为当前入口类所在包及子包。修饰范围: 只能用在类上
@RequestMapping: //作用:用来加入访问路径 修饰范围: 类 (加入命名空间) 方法上(指定具体路径)
@GetMapping: //作用:限定请求方式只能是GET,并指定路径 修饰范围: 方法上
@PostMapping @DeleteMapping @PutMapping……
main 方法的作用: //通过标准java入口方式委托给SpringApplication,并告知当前springboot主应用类是谁,从而启动springboot中tomcat容器
args作用: 可以在启动时指定外部参数
starers: 启动器
springboot-starter-xxx Starters是一组方便的依赖关系描述符
在springboot中提供两种方式配置class 通过springboot 管理自定义java class
a.java config java配置 自定义java对象管理 [推荐]
@Configuration 注解类似于@Component注解 多个自定义对象管理 [推荐]
@import 直接导入一个配置类 只能导入指定对象
b.xml方式配置 通过xml配置管理java对象 [了解]
在resources里面新建spring.xml
<bean id="user" class="com.baizhi.entity.User">bean>
入口类加注解@ImportResource("spring.xml")
在resources中新建banner.txt
# 前面加自定义的banner
spring boot: ${spring-boot.version}
spring boot: ${spring-boot.formatted-version}
#说明: 在实际开发过程中生产环境和测试环境有可能是不一样的 因此将生产中的配置和测试中的配置拆分开,是非常必要的在springboot中也提供了配置文件拆分的方式. 这里以生产中项名名称不一致为例:
生产中项目名为: cmfz
测试中项目名为: springboot
端口同时为: 8080
拆分如下:
#主配置文件:
application.yml #用来书写相同的的配置
server:
port: 8080 #生产和测试为同一个端口
(若指定项目名:servlet:
context-path: /springboot_day1 #指定当前应用在部署到内嵌容器中的项目名
则网址改为localhost:8080/springboot_day1/hello/hello)
#生产配置文件:
application-pord.yml
server:
context-path: /cmfz
#测试配置文件:
application-dev.yml
server:
context-path: /springboot
# 若采用application.properties(另一种配置文件格式)
server.port=8989
server.servlet.context-path=/springboot_day2
(设置懒加载,即延迟初始化,spring.main.lazy-initialization=true,默认不开启)
spring.profiles.active=dev # 选择加载哪个配置文件,可以把公共的配置放在主配置文件中,不同的配置放在其他配置文件中
#生产配置文件:
application-pord.yml
server.port=8081
#测试配置文件:
application-dev.yml
server.port=8089
在springboot中可以管理自定义的
简单组件
对象的创建可以直接使用注解形式创建。
# 1.使用 @Repository @Service @Controller 以及@Component管理不同简单对象
如: 比如要通过工厂创建自定义User对象:
@Component
@Data
public class User {
private String id;
private String name;
......
}
# 2.通过工厂创建之后可以在使用处任意注入该对象
如:在控制器中使用自定义简单对象创建
@Controller
@RequestMapping("hello")
public class HelloController {
@Autowired
private User user;
......
}
在springboot中如果要管理
复杂对象
必须使用@Configuration + @Bean
注解进行管理
# 1.管理复杂对象的创建
@Configuration(推荐)|@Component(不推荐)
public class Beans {
@Bean//(name = "aaa") //用来将改方法返回值交给springboot管理 在工厂中默认标识:类名首字母小写
@Scope("prototype") //prototype 默认为单例singleton
public Calendar getCalendar(){
return Calendar.getInstance();
}
}
# 2.使用复杂对象
@Controller@RequestMapping("hello")public class HelloController { @Autowired private Calendar calendar; ......}
# 注意: 1.@Configuration 配置注解主要用来生产多个组件交给工厂管理 (注册形式) 2.@Component 用来管理单个组件 (包扫描形式)
springboot中提供了三种注入方式:
注入基本属性
,对象注入
# 1.@Value 属性注入 [重点]
@RestController
@RequestMapping("hello")
public class HelloController {
@Value("${name}")
private String name;
@Value("${server.port}")
private int port;
@Value("${bir}")
private Date bir;
@Value("${strs}")
private String[] strs;
@Value("${qqs}")
private List<String> qqs;
@Value("#{${maps}}")
private Maps<String,String> maps;
}
@GetMapping("hello")
public String hello1(){
System.out.println("hello springboot");
System.out.println("name = " + name);
System.out.println("port = " + port);
System.out.println("bir = " + bir);
for (String str : strs) {
System.out.println(str);
}
qqs.forEach(qq-> System.out.println("qq = " + qq));
maps.forEach((k,v)-> System.out.println("k=" + k+" v="+v));
return "hello springboot !!!";
}
# 2.在配置文件中注入
name=xiaochen
bir=2012/12/12 12:12:12
strs=aa,bb,cc
qqs=xiaochen,xiaohei,xiaoming
maps={'aa':'xiaochen','bb':'xiaohei','cc':'xiaosan'}
# 1. @ConfigurationProperties(prefix="前缀")
@Component
@Data
@ConfigurationProperties(prefix = "user")
public class User {
private String id;
private String name;
private Integer age;
private String bir;
public User(String id, String name, Integer age, Date bir) {
this.id = id;
this.name = name;
this.age = age;
this.bir = bir;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBir() {
return bir;
}
public void setBir(Date bir) {
this.bir = bir;
}
@Override
public String toString() {
return "User{" +
"id='" + id + '\'' +
", age=" + age +
'}';
}
public User() {
}
public User(String id, Integer age) {
this.id = id;
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
# 2. 编写配置文件
properties时:
user.id=21
user.age=23
……
yml时:
user:
id: 24
name: xiaohei
age: 23
bir: 2012/12/12
# 3. 引入依赖构建自定义注入元数据
# 引入依赖后配置中也有自动提示
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
<optional>trueoptional>
dependency>
<dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-webartifactId>dependency><dependency> <groupId>jstlgroupId> <artifactId>jstlartifactId> <version>1.2version>dependency><dependency> <groupId>org.apache.tomcat.embedgroupId> <artifactId>tomcat-embed-jasperartifactId>dependency><dependency> <groupId>org.projectlombokgroupId> <artifactId>lombokartifactId> <version>1.18.8version> <scope>providedscope>dependency>
<build>
<finalName>springboot_day1finalName>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<configuration>
<jvmArguments>-Dfile.encoding=UTF-8jvmArguments>
configuration>
plugin>
plugins>
build>
#在配置文件中引入视图解析器
properties版本:
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp
yml版本:
spring:
mvc:
view:
prefix: / # /代表访问项目中webapp中页面
suffix: .jsp
http://localhost:8989/cmfz/index.jsp
server.servlet.jsp.init-parameters.development=true
# HelloController.java @RestController@RequestMapping("hello")public class HelloController { @RequestMapping("hello") public String hello(){ System.out.println(" hello springboot!" ); return "hello springboot"; }}
# UserController.java@Controller@RequestMapping("user")public class UserController { @GetMapping("findAll") public String findAll(HttpServletRequest request, Model model){ System.out.println("查询所有"); model.addAttribute("name","xiaochen"); List<User> users = Arrays.asList(new User("21", "陈晨", 23, new Date()),new User("22", "小陈", 23, new Date())); model.addAttribute("users", users); return "back/index";//逻辑名 前缀+逻辑名+后缀 = /back/index.jsp,此时jsp文件在webapp//back/index.jsp }}
# User.java@Data@AllArgsConstructor@ToStringpublic class User { private String id; private String name; private Integer age; private Date bir;}
# application.properties
server.port=8080
server.servlet.jsp.init-parameters.development=true
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp
# index.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<html>
<body>
<h2>this is Back Directory Hello World!h2>
<h1>获取项目名: ${requestScope.name} ${name}h1>
<c:forEach items="${requestScope.users}" var="user">
${user.id} ==== ${user.name} ==== ${user.age} ==== ${user.bir} <br>
c:forEach>
this is xiaochen
body>
html>
Thymeleaf是一个用于web和独立环境的现代服务器端Java模板引擎。 --摘自官网https://www.thymeleaf.org/
Thymeleaf
是跟Velocity、FreeMarker类似的模板引擎,它可以完全替代JSP,相较与其他的模板引擎相比, Thymeleaf在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。jsp模板只能在有网络下运行,所以更推荐Thymeleaf模板、
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
spring.thymeleaf.prefix=classpath:/templates/ #使用模板目录
spring.thymeleaf.suffix=.html #使用模板后缀
spring.thymeleaf.encoding=UTF-8 #使用模板编码
spring.thymeleaf.enabled=true #开始thymelaf模板
spring.thymeleaf.servlet.content-type=text/html #使用模板响应类型
@Controller //一定要是@Controller 不能再使用@RestController注解
@RequestMapping("hello")
public class HelloController {
@GetMapping("hello")
public String hello(){
System.out.println("测试与 thymeleaf 的集成");
return "index";
}
}
http://localhost:8989/springboot_day3/hello/hello
spring.resources.static-locations=classpath:/templates/,classpath:/static/
http://localhost:8989/springboot_day3/index.html
使用时必须在页面中加入thymeleaf如下命名空间:
<html lang="en" xmlns:th="http://www.thymeleaf.org">
model.addAttribute("name","张三"); 或 request.setAttribute("name","小黑");
<span th:text="${name}"/> --->获取数据
注意:在springboot2.x版本中必须加入国际化配置文件才能正常展示:
model.addAttribute("name","张三");model.addAttribute("username","小陈");
<span th:text="${name}"/>
<span th:utext="${name}"/>
将数据赋值给表单元素
<input type="text" th:value="${username}"/>
# 总结 1.使用 th:text="${属性名}" 获取对应数据,获取数据时会将对应标签中数据清空,因此最好是空标签 2.使用 th:utext="${属性名}" 获取对应的数据,可以将数据中html先解析在渲染到页面 3.使用 th:value="${属性名}" 获取数据直接作为表单元素value属性
model.addAttribute("user",new User("21","xiaochen",23,new Date()));
id:<span th:text="${user.id}">span>name:<span th:text="${user.name}">span>age:<span th:text="${user.age}">span>bir: <span th:text="${user.bir}">span> ==== <span th:text="${#dates.format(user.bir, 'yyyy-MM-dd HH:mm')}">span> 日期格式化
model.addAttribute("user",new User("21","xiaochen",23,new Date()));
<span th:if="${user.age} eq 23">
青年
span>
# 运算符
gt:great than(大于)>
ge:great equal(大于等于)>=
eq:equal(等于)==
lt:less than(小于)<
le:less equal(小于等于)<=
ne:not equal(不等于)!=
<ul th:each="user:${users}">
<li th:text="${user.id}">li>
<li th:text="${user.name}">li>
<li th:text="${user.age}">li>
<li th:text="${#dates.format(user.bir,'yyyy-MM-dd')}">li>
ul>
<ul th:each="user,userStat:${users}">
<li><span th:text="${userStat.count}"/>-<span th:text="${user.id}"/>li> 获取遍历次数 count 从1开始 index 从0开始
<li><span th:text="${userStat.odd}"/>-<span th:text="${user.name}"/>li> 获取当前遍历是否是奇数行
<li><span th:text="${userStat.even}"/>-<span th:text="${user.age}"/>li> 获取当前遍历是否是偶数行
<li><span th:text="${userStat.size}"/>-<span th:text="${user.bir}"/>li> 获取当前集合的总条数
ul>
使用thymeleaf模板项目中静态资源默认放在resources路径小static目录中
<link rel="stylesheet" th:href="@{/css/index.css}">
<script th:src="@{/js/jquery-min.js}">script>
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.3
com.alibaba
druid
1.1.12
mysql
mysql-connector-java
5.1.38
>说明:由于springboot整合mybatis版本中默认依赖mybatis 因此不需要额外引入mybati版本,否则会出现冲突
spring:
mvc:
view:
prefix: /
suffix: .jsp
datasource:
type: org.apache.commons.dbcp.BasicDataSource #指定连接池类型
driver-class-name: com.mysql.jdbc.Driver #指定驱动
url: jdbc:mysql://localhost:3306/cmfz #指定url
username: root #指定用户名
password: root #指定密码
#配置文件中加入如下配置:mybatis: mapper-locations: classpath:com/baizhi/mapper/*.xml #指定mapper配置文件位置 type-aliases-package: com.baizhi.entity #指定起别名来的类
//入口类中加入如下配置:@SpringBootApplication@MapperScan("com.baizhi.dao") //必须在入口类中加入这个配置public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); }}
CREATE TABLE `t_clazz` ( `id` varchar(40) NOT NULL, `name` varchar(80) DEFAULT NULL, `no` varchar(90) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
public class Clazz {
private String id;
private String name;
private String no;
//get set 方法省略....
}
public interface ClazzDAO {
List<Clazz> findAll();
}
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.baizhi.dao.ClazzDAO">
<select id="findAll" resultType="Clazz">
select * from t_clazz
select>
mapper>
//接口
public interface ClazzService {
List<Clazz> findAll();
}
//实现
@Service
@Transactional
public class ClazzServiceImpl implements ClazzService {
@Autowired
private ClazzDAO clazzDAO;
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public List<Clazz> findAll() {
return clazzDAO.findAll();
}
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
@RunWith(SpringRunner.class)@SpringBootTest(classes = Application.class)public class TestClazzService { @Autowired private ClazzService clazzService; @Test public void test(){ List<Clazz> all = clazzService.findAll(); for (Clazz clazz : all) { System.out.println(clazz); } }}
在springboot中默认对jsp运行为生产模式,不允许修改内容保存后立即生效,因此在开发过程需要调试jsp页面每次需要重新启动服务器这样极大影响了我们的效率,为此springboot中提供了可以将默认的生产模式修改为调试模式,改为调试模式后就可以保存立即生效,如何配置为测试模式需要在配置文件中加入如下配置即可修改为开发模式。
server: port: 8989 jsp-servlet: init-parameters: development: true #开启jsp页面的调试模式
为了进一步提高开发效率,springboot为我们提供了全局项目热部署,日后在开发过程中修改了部分代码以及相关配置文件后,不需要每次重启使修改生效,在项目中开启了springboot全局热部署之后只需要在修改之后等待几秒即可使修改生效。
ps:热部署会增加内存,所以一般在生产过程中关闭,开发过程才打开。
<dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-devtoolsartifactId> <optional>trueoptional>dependency>
# 1.开启自动编译 Preferences | Build, Execution, Deployment | Compiler -> 勾选上 Build project automatically 这个选项# 2.开启允许在运行过程中修改文件 ctrl + alt + shift + / ---->选择1.Registry ---> 勾选 compiler.automake.allow.when.app.running 这个选项
# 1.启动出现如下日志代表生效
2019-07-17 21:23:17.566 INFO 4496 --- [ restartedMain] com.baizhi.InitApplication : Starting InitApplication on chenyannandeMacBook-Pro.local with PID 4496 (/Users/chenyannan/IdeaProjects/ideacode/springboot_day1/target/classes started by chenyannan in /Users/chenyannan/IdeaProjects/ideacode/springboot_day1)
2019-07-17 21:23:17.567 INFO 4496 --- [ restartedMain] com.baizhi.InitApplication : The following profiles are active: dev
2019-07-17 21:23:17.612 INFO 4496 --- [ restartedMain] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@66d799c5: startup date [Wed Jul 17 21:23:17 CST 2019]; root of context hierarchy
2019-07-17 21:23:18.782 INFO 4496 --- [ restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8989 (http)
2019-07-17 21:23:18.796 INFO 4496 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-07-17 21:23:18.797 INFO 4496 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.20
注意:日志出现restartedMain代表已经生效,在使用热部署时如果遇到修改之后不能生效,请重试重启项目在试
Logback是由log4j创始人设计的又一个开源日志组件。目前,logback分为三个模块:logback-core,logback-classic和logback-access。是对log4j日志展示进一步改进
> DEBUG < INFO < WARN < ERROR < OFF
>
> 日志级别由低到高: `日志级别越高输出的日志信息越少`
> 日志分为两类
>
> 一种是rootLogger : 用来监听项目中所有的运行日志 包括引入依赖jar中的日志
>
> 一种是logger : 用来监听项目中指定包中的日志信息
> logback的配置文件必须放在项目根目录中 且名字必须为logback.xml
<configuration>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern> [%p] %d{yyyy-MM-dd HH:mm:ss} %m %npattern>
layout>
appender>
<root level="INFO">
<appender-ref ref="stdout"/>
root>
<logger name="com.baizhi.dao" level="DEBUG"/>
configuration>
@Controller
@RequestMapping("/hello")
public class HelloController {
//声明日志成员
private static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(HelloController.class);
@RequestMapping("/hello")
@ResponseBody
public String hello(){
System.out.println("======hello world=======");
logger.debug("DEBUG");
logger.info("INFO");
logger.warn("WARN");
logger.error("ERROR");
return "hello";
}
}
logging:
level:
root: debug
com.baizhi.dao: debug
path: /Users/chenyannan/aa.log
file: bbb.log
springboot是对原有项目中spring框架和springmvc的进一步封装,因此在springboot中同样支持spring框架中AOP切面编程,不过在springboot中为了快速开发仅仅提供了注解方式的切面编程.
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-aopartifactId>
dependency>
/**
@Aspect 用来类上,代表这个类是一个切面
@Before 用在方法上代表这个方法是一个前置通知方法
@After 用在方法上代表这个方法是一个后置通知方法 @Around 用在方法上代表这个方法是一个环绕的方法
@Around 用在方法上代表这个方法是一个环绕的方法
**/
@Aspect
@Component
public class MyAspect {
@Before("execution(* com.baizhi.service.*.*(..))")
public void before(JoinPoint joinPoint){
System.out.println("前置通知");
joinPoint.getTarget();//目标对象
joinPoint.getSignature();//方法签名
joinPoint.getArgs();//方法参数
}
}
@Aspect
@Component
public class MyAspect {
@After("execution(* com.baizhi.service.*.*(..))")
public void before(JoinPoint joinPoint){
System.out.println("后置通知");
joinPoint.getTarget();//目标对象
joinPoint.getSignature();//方法签名
joinPoint.getArgs();//方法参数
}
}
> **注意: 前置通知和后置通知都没有返回值,方法参数都为joinpoint**
@Aspect
@Component
public class MyAspect {
@Around("execution(* com.baizhi.service.*.*(..))")
public Object before(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("进入环绕通知");
proceedingJoinPoint.getTarget();//目标对象
proceedingJoinPoint.getSignature();//方法签名
proceedingJoinPoint.getArgs();//方法参数
Object proceed = proceedingJoinPoint.proceed();//放行执行目标方法
System.out.println("目标方法执行之后回到环绕通知");
return proceed;//返回目标方法返回值
}
}
注意: 环绕通知存在返回值,参数为ProceedingJoinPoint,如果执行放行,不会执行目标方法,一旦放行必须将目标方法的返回值返回,否则调用者无法接受返回数据
定义:用户访问当前系统,将自己本地计算机中文件通过浏览器上传到当前系统所在的服务器过程中称之为文件的上传
<form action="路径...." method="post" enctype="multipart/form-data">
<input type="file" name="aa">
<input type="submit" value="上传">
form>
@Controller
@RequestMapping("/file")
public class FileController {
@RequestMapping("/upload")
public String upload(MultipartFile aa, HttpServletRequest request) throws IOException {
String realPath = request.getRealPath("/upload");
aa.transferTo(new File(realPath,aa.getOriginalFilename()));//文件上传
return "index";
}
}
#上传时出现如下异常: 上传文件的大小超出默认配置 默认10M
nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (38443713) exceeds the configured maximum (10485760)
#修改上传文件大小:
旧版
spring:
http:
multipart:
max-request-size: 209715200 #用来控制文件上传大小的限制
max-file-size: 209715200 #用来指定服务端最大文件大小
新版
spring.servlet.multipart.max-file-size=500MB
spring.servlet.multipart.max-request-size=500MB
<a href="../file/download?fileName=corejava.txt">corejava.txta>
@RequestMapping("/download")
public void download(String fileName, HttpServletRequest request, HttpServletResponse response) throws Exception {
String realPath = request.getRealPath("/upload");
FileInputStream is = new FileInputStream(new File(realPath, fileName));
ServletOutputStream os = response.getOutputStream();
response.setHeader("content-disposition","attachment;fileName="+ URLEncoder.encode(fileName,"UTF-8"));
IOUtils.copy(is,os);
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(os);
}
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
System.out.println("======1=====");
return true;//返回true 放行 返回false阻止
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("=====2=====");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) throws Exception {
System.out.println("=====3=====");
}
}
//1.x中拦截器配置
@Component
public class InterceptorConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//添加拦截器
registry.addInterceptor(new MyInterceptor())
.addPathPatterns("/**")//定义拦截路径
.excludePathPatterns("/hello/**"); //排除拦截路径
}
}
//2.x中拦截器配置
@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor())//添加拦截器
.addPathPatterns("/hello/**")//添加拦截的请求路径
.excludePathPatterns("/hello/world");//添加排除那些请求路径不经过拦截器
}
}
注意:在springboot2.x版本中自定义拦截器之后出现项目中静态资源 404情况,需要在自定义拦截器的配置中加入如下配置即可:
@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/file/**")
.excludePathPatterns("/js/**", "/css/**", "/files/**");//放行静态资源 静态资源被认为是一个控制器请求
}
//springboot2.x 静态资源在自定义拦截器之后无法访问的解决方案
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**") //代表以什么样的请求路径访问静态资源
.addResourceLocations("classpath:/static/")
.addResourceLocations("classpath:/templates/");
}
}
war
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<configuration>
<fork>truefork>
<jvmArguments>-Dfile.encoding=UTF-8jvmArguments>
<mainClass>com.baizhi.ApplicationmainClass>
configuration>
plugin>
plugins>
build>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-tomcatartifactId>
<scope>providedscope>
dependency>
<dependency>
<groupId>org.apache.tomcat.embedgroupId>
<artifactId>tomcat-embed-jasperartifactId>
<scope>providedscope>
dependency>
//1.继承SpringBootServletInitializer
//2.覆盖configure方法
public class Application extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(Application.class);
}
}
/* 一旦使用war包部署注意:
1. application.yml 中配置port context-path 失效
2. 访问时使用打成war包的名字和外部tomcat端口号进行访问项目
*/