简介
Spring Boot使开发独立的,产品级别的基于Spring的应用变得非常简单,你只需"just run"。 我们为Spring平台及第三方库提供开箱即用的设置,这样你就可以有条不紊地开始。多数Spring Boot应用需要很少的Spring配置。你可以使用Spring Boot创建Java应用,并使用java -jar启动它或采用传统的war部署方式
解决问题
- 依赖太多了, 且存在版本问题
- 配置太多了且每次都一样, 大部分工程, 配置每次都是一样的, 从一个地方拷贝到另外一个地方. 且Spring发展10多年, 各种配置版本太多, 对于很多程序员来说, 分不清哪个是有效, 哪个无效.
- 部署太麻烦. 需要tomcat部署, 项目结构也需要照着Java EE的目录结构来写.
SpringBoot特点
- 创建独立的Spring应用程序
- 嵌入的Tomcat,无需部署WAR文件
- 简化Maven配置
- 自动配置Spring
- 提供生产就绪型功能,如指标,健康检查和外部配置
- 绝对没有代码生成和对XML没有要求配置
第一个SpringBoot程序
1.新建一个maven项目
pom文件引入
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
新建一个类Example.java
package com.springbootstudy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@EnableAutoConfiguration
public class Example {
@RequestMapping("/")
String home() {
return "Hello World!";
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Example.class, args);
}
}
/*
@RestController和@RequestMapping说明:
@RestController。这被称为一个构造型(stereotype)注解。它为阅读代码的人们提供建议。对于Spring,该类扮演了一个特殊角色。在本示例中,我们的类是一个web @Controller,所以当处理进来的web请求时,Spring会询问它。
@RequestMapping注解提供路由信息。它告诉Spring任何来自"/"路径的HTTP请求都应该被映射到home方法。@RestController注解告诉Spring以字符串的形式渲染结果,并直接返回给调用者。
@EnableAutoConfiguration。这个注解告诉Spring Boot根据添加的jar依赖猜测你想如何配置Spring。由于spring-boot-starter-web添加了Tomcat和Spring MVC,所以auto-configuration将假定你正在开发一个web应用并相应地对Spring进行设置。
main方法。这只是一个标准的方法,它遵循Java对于一个应用程序入口点的约定。我们的main方法通过调用run,将业务委托给了Spring Boot的SpringApplication类。SpringApplication将引导我们的应用,启动Spring,相应地启动被自动配置的Tomcat web服务器。我们需要将Example.class作为参数传递给run方法来告诉SpringApplication谁是主要的Spring组件。
*/
运行main方法
上面证实访问成功,开始访问
OK,到此,第一个Helloword就写完了。
整合Mybatis做登陆注册
修改项目
还在这个项目的基础上做。
新建一个UserController
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@RequestMapping("/hello")
public String sayHello() {
return "Hello*****";
}
}
修改Example
package com.springbootstudy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
//@MapperScan 扫描mapper所在的包 就可以不在dao层加@mapper注解了
public class Example {
public static void main(String[] args) throws Exception {
SpringApplication.run(Example.class, args);
}
}
启动Example的main方法 在浏览器输入localhost:8080/hello 输出hello证明基本环境搭建成功
整合Mybatis
修改pom文件新增如下依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
service层和dao层mapper映射文件就不写了
略。。。。。。。
配置文件在resource文件夹下新建application.properties
# 数据源
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/clouddb01?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root
# 配置Mybatis Mapper映射文件所在位置
mybatis.mapperLocations=classpath:mapper/*.xml
至此自己就可以写测试方法测试了,下面是我写的
UserTest.java
@SpringBootTest(classes = App.class)
@RunWith(SpringRunner.class)
public class UserTest {
@Resource
private UsersMapper usersMapper;
@Test
public void testAdd() {
Users user = new Users() ;
user.setPasswd("123");
user.setUsername("enjoy");
usersMapper.insertSelective(user);
}
@Test
public void testFindUser() {
Users enjoy = usersMapper.findByUsernameAndPasswd("enjoy", "123");
System.out.println(enjoy);
}
}
浏览器测试,修改UserController.java
package com.springbootstudy.controller;
import com.springbootstudy.service.IUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class UserController {
private final Logger logger = LoggerFactory.getLogger(UserController.class);
@Resource
private IUserService iUserService;
@RequestMapping("/hello")
public Object sayHello() {
logger.debug("这是个hello的日志");
return "hello";
}
@RequestMapping("/login")
public String login(String username,String passwd) {
boolean login = iUserService.login(username, passwd);
if(login) {
return "登陆成功";
}else {
return "登陆失败";
}
}
@RequestMapping("/register")
public String register(String username,String passwd) {
boolean login = iUserService.register(username, passwd);
if(login) {
return "注册成功";
}else {
return "注册失败";
}
}
@RequestMapping("/batchAdd")
public String batchAdd(String username,String passwd) {
iUserService.batchAdd(username, passwd);
return "成功";
}
}
如下表示成功
小知识点 新增的时候的事务
全局异常
上面事务里面显示异常的时候界面会显示错误,但是加上全局异常处理后显示自己所处理的异常,步骤如下,新建一个GlobalExceptionHandler.java处理全局异常
结果再有异常时的显示为
上面的处理了程序运行时异常,但是访问咱们的系统的时候如果没有这个路径,还是会报错,咋解决的,看下面
结果如下
上面那个异常处理类的所有代码如下
package com.springbootstudy.util;
import org.springframework.boot.web.server.ConfigurableWebServerFactory;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
@ControllerAdvice //会拦截所有的@RequestMapping
public class GlobalExceptionHandler {
//拦截到了后捕获异常
@ExceptionHandler(value = RuntimeException.class)
@ResponseBody
public Object defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
e.printStackTrace();
return "我是个异常处理类";
}
@Bean
public WebServerFactoryCustomizer<ConfigurableWebServerFactory> webServerFactoryCustomizer(){
WebServerFactoryCustomizer<ConfigurableWebServerFactory> result = new WebServerFactoryCustomizer<ConfigurableWebServerFactory>() {
@Override
public void customize(ConfigurableWebServerFactory factory) {
ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/404.do");
factory.addErrorPages( error404Page);
}
};
//jdk 1.8 lambda
// return (factory->{
// ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/404.do");
// factory.addErrorPages( error404Page);
// });
return result;
}
}
访问静态资源
有个小规律放到/static或者/public目录下
好了,访问看看
整合JSP
一般来说,springboot不太愿意咱们写jsp呢,为啥呢,因为jsp需要web容器的支持,但是现在的趋势是搞前后端分离。
修改pom添加jsp的支持
<!--JavaServer Pages Standard Tag Library,JSP标准标签库-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!--内置tocat对Jsp支持的依赖,用于编译Jsp-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
修改配置文件,添加jsp视图解析
# 配置视图解析器
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
新建上边的目录,注意webapp建在main下
写个测试类,测试一下
package com.springbootstudy.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/jsp")
public class JspController {
@RequestMapping("/hi")
public String sayHello() {
return "index";
}
}
测试结果,没毛病。
日志基本使用
java有许多的日志组件,比如 log4j,log4j2,logback还有java自生提供的Java Util Logging,其实在springboot中对这些组件都提供了支持,log4j,log4j2和logback都提供相应的组件支持。
这里提一下SLF4J(Simple Logging Facade for Java)
即简单日志门面。SLF4J并不是具体的日志框架,而是作为一个简单门面服务于各类日志框架,如java.util.logging, logback和log4j。SLF4J提供了统一的记录日志的接口,对不同日志系统的具体实现进行了抽象化,只要按照其提供的方法记录即可,最终日志的格式、记录级别、输出方式等通过绑定具体的日志系统来实现。相当于JDBC。SpringBoot内置集成了logback。下图证明
使用的话直接调用就i好了
修改日志级别,修改配置文件
# 日志级别
logging.level.root=INFO
# 这个包的日志级别是debug
logging.level.com.springbootstudy.controller=debug
日志存储 修改配置文件
# 日志路径 两个都定义的话logging.file生效
# 如果只定义logging.path 会在这个路径下生成一个spring.log
logging.path=
# 只定义这个 会在项目的跟路径下生成一个xxx.log文件
logging.file=F:\\log\\test.log
将logback改为其他的修改pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!--排除所有的默认日志-->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
用法同上
AOP
添加pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
新增日志处理类WebLogAspect.java
package com.springbootstudy.util;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
@Aspect
@Component
public class WebLogAspect {
private static final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
//切点 拦截所有的controller 所有的方法
@Pointcut("execution(public * com.springbootstudy.controller.*.*(..))")
public void webLog() {
}
//调用方法之前
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 记录下请求内容
logger.info("URL : " + request.getRequestURL().toString());
logger.info("HTTP_METHOD : " + request.getMethod());
logger.info("IP : " + request.getRemoteAddr());
Enumeration<String> enu = request.getParameterNames();
while (enu.hasMoreElements()) {
String name = (String) enu.nextElement();
logger.info("name:{},value:{}", name, request.getParameter(name));
}
}
//方法执行后
@AfterReturning(returning = "ret", pointcut = "webLog()")
public void doAfterReturning(Object ret) throws Throwable {
// 处理完请求,返回内容
logger.info("RESPONSE : " + ret);
}
}
测试