SpringBoot

AnnotationConfig


注解配置,Spring3.0,SpringIO 团队摆脱 XML 配置文件,开发过程中大量使用 “约定优先配置”。用 Java 类代替 XML。
JavaConfig 功能已经包含了 Spring 核心模块,它允许开发者将 bean 的定义和 Spring 的配置编写到 Java 类中,仍然允许使用经典的 XML 方式定义 bean 和 配置 Spring,JavaConfig 也叫 AnnotationConfig。

准备工作

使用 Maven 创建 JavaSE 项目,在 pom.xml 中添加 Spring 依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>cn.lizhaoloveit</groupId>
<artifactId>springboot</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>5.1.0.RELEASE</spring.version>
</properties>

<dependencies>

<!-- JUnit4测试工具 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>

<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>

<!-- lombok插件 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.6</version>
<scope>provided</scope>
</dependency>
</dependencies>

<build>
<plugins> <!--Java编译器插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>

以前使用 spring 创建对象的方式

applicationContext.xml

1
<bean id="someBean" class="cn.lizhaoloveit.javaconfig.common.SomeBean"/>
1
2
3
4
5
6
@Test
public void test() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
SomeBean bean = ctx.getBean(SomeBean.class);
System.out.println(bean);
}

现在使用 JavaConfig 创建对象

使用添加组件扫描器

添加组件扫描器的方式减少方法的定义,只能减少我们自定义的组件,不是我们自定义的组件必须要在 AppConfig 中配置。

1
2
3
4
@Configuration // 表示该类是 Spring 配置类
// 开启组件扫描器,默认扫描(不写 value 时)当前类所在的包,及子包
@ComponentScan("cn.lizhaoloveit.common")
public class AnnotationConfig {}

如果需要扫描的包不是配置类所在包时,通过注解中的 value 属性修改要扫描的包
组件扫描的方式只能扫描我们自己的组件,如果 bean 不是我们自己写的,还是需要通过在配置类中定义方法来处理。两者可以同时存在。

一般用法:项目中一般把使用组件扫描器的配置类放在项目的外面,使用 @ComponentScan 默认值即可,默认扫描当前配置类所在的包以及子包

SpringTest 加载配置类

传统方式

1
2
3
@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration("classpath:xml文件路径")
public class App { ... }

AppConfig

1
2
3
@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes={配置类1.class, 配置类2.class, ...})
public class App { ... }

Bean 注解中的属性


bean 的 id 相当于当前方法名。配置多例则是在方法上添加 @Scope("prototype")注解实现,一般不用。

DI 注入

传统方式:

1
2
3
<bean id="someBean" class="cn.wolfcode.common.someBean"> <property name="otherBean" ref="otherBean"/> </bean>

<bean id="otherBean" class="cn.wolfcode.common.OtherBean"/>

在 AppConfig 中有两种方式完成依赖注入,两种方式的第一步都是先把 bean 交给 Spring 管理。

1
2
3
4
5
6
7
8
@Bean 
public SomeBean someBean() {
SomeBean someBean = new SomeBean();
return someBean;
}

@Bean
public OtherBean otherBean() { return new OtherBean(); }

第一种

1
2
3
4
5
6
7
8
9
10
11
/**
* 在声明 SomeBean 的方法形参中直接注入 OtherBean 对象
* @return
*/
@Bean
public SomeBean someBean(OtherBean otherBean) {
// 创建 SomeBean 对象的过程
SomeBean bean = new SomeBean();
bean.setOtherBean(otherBean);
return bean;
}

第二种

1
2
3
4
5
6
7
8
9
10
@Bean 
public SomeBean someBean() {
SomeBean someBean = new SomeBean();
/**
* 调用otherBean()方法,拿到容器创建的otherBean对象
* 然后赋值给SomeBean的属性,完成依赖注入
*/
someBean.setOtherBean(otherBean());
return someBean;
}

配置文件的导入

Spring 项目中一般会有多个 Spring 的配置文件,分别配置不同的组件,最后关联到主配置文件中。

传统方式

1
<import resource="classpath:applicationContext.xml"/>

AppConfig

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 主配置文件
@Configuration
@Import(OtherConfig.class) // 引入其他配置文件
public class MainConfig {
@Bean
public SomeBean someBean(OtherBean otherBean) {
// 创建 SomeBean 对象的过程
SomeBean bean = new SomeBean();
bean.setOtherBean(otherBean);
return bean;
}
}


// 其他配置文件
@Configuration
public class OtherConfig {
@Bean
public OtherBean otherBean() {
return new OtherBean();
}
}

// 测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = MainConfig.class) // 加载主配置类
@ImportResource("classpath:applicationContext.xml") // 如果配置类为 xml 使用该注解加载配置
public class AppTest {
@Autowired
private SomeBean someBean;

@Test
public void test() {
System.out.println(someBean);
// 打印 SomeBean(otherBean=cn.lizhaoloveit.javaconfig.common.OtherBean@cd3fee8)
}
}

注入属性文件


传统方式

1
2
3
4
5
6
7
8
<context:property-placeholder location="classpath:db.properties" system-properties-mode="NEVER"/>

<!-- 连接池对象 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>

AppConfig

方式一: 使用 @PropertySource + @Value 注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@Configuration
// 加载 properties
@PropertySource("classpath:dev.properties")
public class DBConfig {
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Bean
public DataSource dataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
return druidDataSource;
}
}

// 测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { MainConfig.class, DBConfig.class }) // 加载主配置类
public class AppTest {
@Autowired
private SomeBean someBean;
@Autowired
private DataSource dataSource;
@Test
public void test() {
System.out.println(someBean);
}
@Test
public void testDataSource() {
System.out.println(dataSource);
}
}

方式二:

直接在配置类中注入 Spring 的环境变量

1
2
3
4
5
6
7
8
9
10
11
12
13
@Configuration 
@PropertySource("classpath:db.properties")
public class AnnotationConfig {
/** * environment:表示Spring的环境对象,该对象包含了加载的属性数据 */
@Autowired
private Environment environment;

@Bean(initMethod="init", destroyMethod="close")
public DruidDataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl(environment.getProperty("jdbc.url")); dataSource.setUsername(environment.getProperty("jdbc.username")); dataSource.setPassword(environment.getProperty("jdbc.password"));
return dataSource;
}
}

属性绑定

在 application.properties 中设置如下属性

1
2
jdbc.username=root
jdbc.password=admin

@Value 绑定单个属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Component // 将 MyDataSource 交给 spring 容器管理
@ToString
public class MyDataSource {
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
}

// 配置文件
// 一系列功能,组件扫描/自动配置/标记配置类,默认加载 application.properties 配置
@SpringBootApplication
public class AppConfig {
public static void main(String[] args) {
SpringApplication.run(AppConfig.class, args);
}
}

// 测试
@RunWith(SpringRunner.class)
@SpringBootTest(classes = AppConfig.class) // 默认加载当前测试类名,去掉后缀Tests,要求测试类和配置类包名一致
public class AppConfigTests {
@Autowired
private MyDataSource dataSource;
@Test
public void testDataSource() {
System.out.println(dataSource);
}
}

ConfigurationProperties 绑定对象属性

1
2
3
4
5
6
7
8
@Component
@ToString
@ConfigurationProperties("jdbc")
@Setter
public class MyDataSource {
private String username;
private String password;
}

或者在配置文件中配置属性并指明前缀。

1
2
3
4
5
@Bean(initMethod = "")
@ConfigurationProperties("jdbc")
public DruidDataSource dataSource() {
return new DruidDataSource();
}

切换运行环境


Springboot 配置 web 项目


搭建环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<version>1.0</version>
<!-- 打包方式jar包 -->
<packaging>jar</packaging>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

HelloSpringboot.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@SpringBootApplication
@Controller
public class HelloSpringboot {

public static void main(String[] args) {
SpringApplication.run(HelloSpringboot.class, args);
}

@RequestMapping("hello")
@ResponseBody
public String hello() {
return "hello Springboot";
}
}

控制台打印如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
2019-09-21 15:44:01.789  INFO 73046 --- [           main] c.l.springboot.HelloSpringboot           : Starting HelloSpringboot on lizhao.local with PID 73046 (/Users/Ammar/Documents/code/practice/springboot-web/target/classes started by Ammar in /Users/Ammar/Documents/code/practice/springboot-web)
2019-09-21 15:44:01.795 INFO 73046 --- [ main] c.l.springboot.HelloSpringboot : No active profile set, falling back to default profiles: default
2019-09-21 15:44:04.069 INFO 73046 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2019-09-21 15:44:04.134 INFO 73046 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-09-21 15:44:04.134 INFO 73046 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.16]
2019-09-21 15:44:04.154 INFO 73046 --- [ main] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/Users/Ammar/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.]
2019-09-21 15:44:04.366 INFO 73046 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-09-21 15:44:04.367 INFO 73046 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2450 ms
2019-09-21 15:44:04.795 INFO 73046 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2019-09-21 15:44:05.356 INFO 73046 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2019-09-21 15:44:05.365 INFO 73046 --- [ main] c.l.springboot.HelloSpringboot : Started HelloSpringboot in 5.348 seconds (JVM running for 18.177)
2019-09-21 15:44:09.646 INFO 73046 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-09-21 15:44:09.646 INFO 73046 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2019-09-21 15:44:09.660 INFO 73046 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 13 ms
  1. 为什么 web 项目打包方式是 jar
  2. spring-boot-starter-parent 是什么
  3. spring-boot-starter-web 又有什么作用
  4. @SpringBootApplication 注解有什么作用
  5. main 方法中执行的代码 SpringApplication.run() 有什么用
  6. Tomcat9 服务器哪里来的

SpringBoot 项目无论是普通应用还是 web 应用,其打包方式都是 jar 包,web 应用也能打 war 包,需要额外添加很多插件。
spring-boot-starter-parent 帮助管理和导入了很多基础依赖 <dependencyManagement> 使用依赖管理,因此项目中导入的依赖不需要添加版本号。直接使用。
在 spring-boot-starter-web 依赖中,嵌入了 Tomcat9 服务器,默认端口是8080,Tomcat 提供了嵌入式的 embed 模式。更加轻便去掉了不经常使用的功能。SpringBoot 提供了非常多以 spring-boot-starter-* 开头的开箱即用的工具包,

工具包 作用
spring-boot-starter 核心的工具包,提供了自动配置,日志和YAML配置支持
spring-boot-starter-aop 提供了快速集成SpringAOP和AspectJ的工具包
spring-boot-starter-freemarker 提供了快速集成FreeMarker的工具包
spring-boot-starter-test 提供了测试SpringBoot应用的工具包
spring-boot-starter-web 提供了快速集成web模块的工具包,包括基于SpringMVC,Tomcat服务器等
spring-boot-starter-actuator 提供了生产环境中使用的应用监控工具包
spring-boot-starter-logging 提供了对日志的工具包,默认使用Logback

@SpringBootApplication 注解内部由3大注解功能集成

  • @ComponentScan 扫描组件,默认扫描当前配置类所在的包及子包
  • @SpringBootConfiguration 作用等同于 @Configuration 注解,标记当前类为配置类
  • @EnableAutoConfiguration 内部导入了 AutoConfigurationImportSelector,该类中的 getCandidateConfigurations 方法,加载了 jar 包中的 META-INF/spring.factories文件中配置的对象,自动配置的功能包括:AOP、PropertyPlaceholder、FreeMarker、HttpMessageConverter、Jackson、DataSource等等。基础功能

SpringApplication.run() 用来启动 SpringBoot 应用,加载自定义的配置类,完成自动配置,把当前项目配置嵌入到 Tomcat 服务器,启动嵌入的 Tomcat 服务器。

如何独立运行 springboot 项目


默认 Maven 打包方式是不能正常打包 SpringBoot 项目的,需要额外的引入打包插件。

1
2
3
4
5
6
7
8
9
10
<!-- pom.xml中添加插件 -->
<build>
<plugins>
<!-- SpringBoot打包插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

使用 package 命令进行打包,使用 java -jar xx.jar 运行 jar 包。
由于版本更新较快,可能出现较大变化,约定大于配置,所以会经常出现一些难以解决的问题。

SpringBoot 项目标准目录结构

SpringBoot 参数配置


参数来源

  1. 命令行启动项目时传入的参数,java -jar xxx.jar –server.port=80
  2. ServletConfig 和 ServletContext
  3. 操作系统环境变量
  4. application-{profile}.properties 或者 YAML 文件
  5. application.properties 或者 YAML 文件

一般用的比较多的是直接在 application.properties 或者 YAML 配置。其次是命令行启动。

配置文件优先级


参数配置优先级,一个项目可以有多个 application.properties 文件存放在不同的目录中,优先级如下:

  1. 当前目录下的子目录config/application.properties
  2. 当前目录下的application.properties
  3. classpath:config/application.properties
  4. classpath:application.properties

一般只在 classpath:application.properties 做配置,其他地方不使用

SpringBoot 在 Web 项目的应用


静态资源

默认情况下,Springboot 会从 classpath:/static/、/public、/resources、/META/resources 下加载静态资源,可以在 application.properties 中配置 spring.resources.staticLocations 属性修改静态资源加载地址,因为应用是打成 jar 包,之前的 src/main/webapp 就作废了,如果有文件上传,必须配置图片所在的路径

application.properties

1
2
# 设置网站的静态资源路径,文件上传
spring.resources.staticLocations=file://E:/img,classpath:/static,classpath:/public

集成 FreeMarker

在传统的SpringMVC中集成FreeMarker需要把FreeMarkerConfigurer和FreeMarkerViewResolve两个对象配置到 Spring容器中,同时两个对象都要分别配置一些属性,还是比较麻烦的
在SpringBoot中,依靠自动配置功能,我们可以非常轻松的实现集成FreeMarker,只需要引入一个依赖即可

1
2
3
4
5
// 当这个 bean 有的时候,该注解贴的方法的 bean 才会创建
@ConditionalOnMissingBean(FreeMarkerConfig.class)

该默认配置
###### @EnableConfigurationProperties(FreeMarkerProperties.class)
1
2
3
4
5
<!-- SpringBoot集成FreeMarker的依赖 --> 
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

SpringBoot 自动配置中含有 FreeMarkerAutoConfiguration 配置对象,该配置对象又导入了 FreeMarkerReactiveWebConfiguration 配置对象,在里面创建了 FreeMarkerConfigurer 和 FreeMarkerViewResolve 两个对象交给 Spring,并且设置了默认的属性值,这些属性值来源于 FreeMarkerProperties 对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
spring.freemarker.enabled=true # 是否开启freemarker支持 
spring.freemarker.allow-request-override # 是否允许request中的属性覆盖model中同名属性,默认false
spring.freemarker.allow-session-override # 是否允许session中的属性覆盖model中同名属性,默认false
spring.freemarker.cache # 是否支持模板缓存,默认false
spring.freemarker.charset=UTF-8 # 模板编码
spring.freemarker.content-type=text/html # 模板contenttype
spring.freemarker.expose-request-attributes # 是否开启request属性暴露,默认false
spring.freemarker.expose-session-attributes # 是否开启session属性暴露,默认false
spring.freemarker.expose-spring-macro-helpers # 是否开启spring的freemarker宏支持,默认为false
spring.freemarker.prefer-file-system-access # 默认为true,支持实时检查模板修改
spring.freemarker.prefix # 加载模板时候的前缀
spring.freemarker.settings.* # 直接配置freemarker参数
spring.freemarker.suffix # 模板文件后缀
spring.freemarker.template-loader-path=classpath:/templates/ # 模板加载地址

一般会做一个配置,其余默认
spring.freemarker.expose-session-attributes=true #暴露session对象的属性

统一异常处理

框架自带方式:SpringBoot 默认情况下,会把所有错误都交给 BasicErrorController 类完成处理,错误的视图导向到 classpath:/static/error/ 和 classpath:/templates/error 路径上,http 状态码就是默认视图的名称。

如: 出现404错误 -> classpath:/static/error/404.html 或者 出现5xx类错误 -> classpath:/static/error/5xx.html

控制器增强,统一处理异常。一般用于 5xx 的错误

1
2
3
4
5
6
7
8
9
@ControllerAdvice //控制器增强器 
public class ExceptionControllerAdvice {

@ExceptionHandler(Exception.class) //处理什么类型的异常
public String handlException(Exception e, Model model) {
model.addAttribute("msg", e.getMessage());
return "errorView"; //逻辑视图名称
}
}

WebMvcConfigurer 接口


WebMvcConfigurer 接口是 JavaConfig 配置 SpringMVC 的标准接口,在 SpringBoot 中,如果需要对 SpringMVC 做配置,配置对象实现该接口。

添加拦截器

在SpringBoot中,需要在配置类中添加方法

1
2
3
4
5
6
7
8
9
10
@SpringBootApplication 
public class AppConfig implements WebMvcConfigurer {
public static void main(String[] args) { SpringApplication.run(AppConfig.class, args); }
public void addInterceptors(InterceptorRegistry registry) {
// 注册拦截器
registry.addInterceptor(拦截器对象) // 对哪些资源起过滤作用
.addPathPatterns("/**") // 对哪些资源起排除作用
.excludePathPatterns("/..");
}
}

SpringBoot 的 SpringMVC 默认的 url-pattern 是 /,如果要改为 *.do。需要做配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@SpringBootApplication 
public class AppConfig implements WebMvcConfigurer {
public static void main(String[] args) { SpringApplication.run(AppConfig.class, args); }
public void configurePathMatch(PathMatchConfigurer configurer) {
//开启后缀匹配模式
configurer.setUseRegisteredSuffixPatternMatch(true);
}

// 重新注册Servlet的映射
@Bean
public ServletRegistrationBean servletRegistrationBean(DispatcherServlet dispatcherServlet){
ServletRegistrationBean<DispatcherServlet> servletServletRegistrationBean =
new ServletRegistrationBean<>(dispatcherServlet);
servletServletRegistrationBean.addUrlMappings("*.do");
return servletServletRegistrationBean;
}
}

集成 Mybatis


准备工作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!-- druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!--mybatis集成到SpringBoot中的依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- SpringBoot集成jdbc的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

配置对象方式

1
2
3
4
#application.properties 
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///rbac?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8 jdbc.username=root
jdbc.password=admin

配置文件:SpringApplication.java

1
2
3
@Bean(initMethod="init", destroyMethod="close") 
@ConfigurationProperties("jdbc")
public DruidDataSource dataSource() { return new DruidDataSource(); }

或者直接在 application.properties 配置文件中配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#application.properties 
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql:///rbac?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
spring.datasource.username=root spring.datasource.password=admin

mybatis.configuration.lazy-loading-enabled=true
mybatis.configuration.lazy-load-trigger-methods=clone
mybatis.mapper-locations=classpath:mapper/*Mapper.xml
mybatis.type-aliases-package=cn.lizhaoloveit.springssm.domain

logging.level.cn.lizhaoloveit.springssm=trace

# SpringBoot默认优先选择CGLIB代理,如果需要改为优先使用JDK代理,需要做以下配置
# 优先使用JDK代理
spring.aop.proxy-target-class=false

SpringBoot 自动配置连接池会先检查容器中是否有连接池对象,没有则会根据特定的属性前缀创建连接池对象交给 Spring 管理。
Mapper 接口扫描器只要在配置类上贴上注解 @MapperScan(…)即可

事务管理


准备依赖,AOP。

1
2
3
4
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>

使用 xml 配置的策略,在配置类上使用 @ImportResource("classpath:spring-tx.xml")
使用注解方式,在 service 层上贴注解 @Transactional 注解。在 properties 文件上加入动态代理方式。

1
2
# SpringBoot 默认预先选择 CGLib 动态代理,如果要改为使用 JDK 代理需要配置如下
spring.aop.proxy-target-class=false

系统日志


SpringBoot 默认已经开启日志,格式如下:

SpringBoot 的日志分为:系统日志和应用日志
SpringBoot 默认选择 Logback 作为日志框架。

使用方式

配置 xml 文件,Logback 默认自动加载 classpath:logback.xml作为配置文件,在 SpringBoot 中使用,额外支持自动加载 classpath:logback-spring.xml,获得额外功能,SpringBoot 中推荐使用 logback-spring.xml

logback-spring.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?xml version="1.0" encoding="UTF-8"?>
<!--scan:开启日志框架的热部署,默认值true表示开启
scanPeriod:热部署的频率,默认值60
second debug:设置输出框架内部的日志,默认值false -->
<configuration scan="true"
scanPeriod="60 second"
debug="false">
<property name="appName" value="springboot demo"/>
<contextName>${appName}</contextName>

<!-- appender:日志输出对象,配置不同的类拥有不同的功能 ch.qos.logback.core.ConsoleAppender:日志输出到控制台 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd-HH:mm:ss} %level [%thread]-%logger{35} >> %msg %n</pattern>
</encoder>
</appender>

<!-- ch.qos.logback.core.FileAppender:日志输出到文件中
<appender name="fileAppender" class="ch.qos.logback.core.FileAppender">
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
<append>true</append>
<file>mylog.log</file>
</appender> -->

<!-- root是项目通用的logger,一般情况下都是使用root配置的日志输出 level:按照级别输出日志,日志级别,级别越高,输出的内容越少 trace > debug > info > warn > error -->
<root level="info">

<appender-ref ref="STDOUT"/>
</root>

<!-- 自定义的logger,用于专门输出特定包中打印的日志
<logger name="cn.wolfcode.springboot" level="trace">
<appender-ref ref="fileAppender" />
</logger> -->
</configuration>

参考日志格式:%d{yyyy-MM-dd-HH:mm:ss} %level [%thread]-%class:%line >> %msg %n

格式中的标识符组成:

  • %logger{n}:输出Logger 对象类名,n代表长度
  • %class{n}:输出所在类名
  • %d{pattern}或者date{pattern}:输出日志日期,格式同java
  • %L/line:日志所在行号
  • %m/msg:日志内容
  • %method:所在方法名称
  • %p/level:日志级别
  • %thread:所在线程名称

类中使用日志输出

自定义的类中如果要用到日志框架输出

1
2
3
4
5
6
7
// 1:在类中定义一个静态日志对象,这步可以使用lombok提供的@Slf4j注解来简化 
private static final Logger log = LoggerFactory.getLogger(类.class);
// 2:在需要输出日志的地方使用日志的输出方法
log.info(...);
log.error(...); ...

// 输出日志中有变量可以使用{}作为占位符,如 log.info("我是{}", "逍遥");

将日志输出到文件中

生产环境中,日志输出只输出 ERROR,生产环境中使用 TRACE。

文章作者: Ammar
文章链接: http://lizhaoloveit.cn/2019/10/01/SpringBoot/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ammar's Blog
打赏
  • 微信
  • 支付宝

评论