项目:Ubuntu--eclipse--springbootInstance1
学习路线图:
SpringBoot简介
- 第一个SpringBoot程序
- 原理初探
- yaml语法
- 多环境配置、配置文件位置
- 配置文件和spring.factories
- 配置文件字段与Properties类属性映射
- @Conditional注解
- 查看所有生效、没生效、排除配置类
[SpringBoot web开发](#SpringBoot web开发)
- 静态资源相关
- 自定义首页、标签页图标
- Thymeleaf模板引擎
- 语法
- 拓展springmvc
网站实现
- 业务逻辑处理
数据库、安全相关
- [整合JDBC](#整合JDBC)
- [SpringSecutiry](#SpringSecutiry)
其他
[eclipse使用Resource Bundle Editor实现属性集编写](#eclipse使用Resource Bundle Editor实现属性集编写)
SpringBoot简介
为了简化SSM整合的配置文件相关的复杂性,spring进行了整合,提出了springBoot,其理念就是约定大于配置。
主要优点:
- 对开发者来说可以更快入门
- 开箱即用:提供各种默认配置来简化项目配置。
- 内嵌式容器(如tomcat)简化Web项目
- 没有冗余代码生成和xml配置的要求
微服务介绍
微服务时一种架构风格,它规定我们在开发一个应用时,应用必须构建成一系列组件的组合(每个组件提供一个小服务);可以通过http方式进行互通。
如何构建微服务:
一个大型系统的微服务架构,就像一个复杂交织的网络,每个节点就是一个功能元素,他们各自完成特定的职责,然后通过http相互请求、调用。
如电商系统:查缓存、连数据库、浏览页面、结账、支付等服务,被微化成一个个独立的微服务,这些微服务共同构建了一个完整而庞大的系统。
当想要修改其中一个服务时,并不需要如All in one类型的项目,停止、重启。而只需要更新一个服务功能,空挡期可以选择一个备用的接口或者返回某个页面来进行提示。
但这样庞大的系统架构给部署和运维带来了很大的难度,于是,spring为我们简化,并提供了全套的微服务架构、产品:
- SpringBoot:帮助快速构建一个应用:包含一个个功能独立的微服务应用单元。
- Spring Cloud:完成大型分布式网络服务的调用。-
- Spring Cloud Data Flow:在分布式中间,进行流式数据计算、批处理。
- spring为我们罗列了构建大型分布式应用,整个流程的方案。
第一个SpringBoot程序
第一种--直接在springboot官网配置好,下载下来,解压缩即可。
第二种--直接在IDEA创建一个springBoot项目(其帮我们去官网下载)
只要创建了项目,就可以直接运行了。http://localhost:8008/也可以启动,显示springBoot提供的提示信息。(使用tomcat作为默认嵌入式容器)
然后可以直接创建Controller类了,并不需要配置web.xml(DispatcherServlet)、Springmvc.xml等文件了,springboot已经帮我们配置了。
application.properties
里面已经包含springboot默认配置的很多依赖了。最主要的是该项目的父项目,即spring-boot-starter-parent,在其内部进行了约定的默认配置。(约定大于配置)
部分配置说明:
首先:springboot已经帮我们配置好了所有东西,此处说一些自定义配置之类的。
-
自定义banner图像:即console启动时显示的图像,可以自定义。
①去网上搜:springboot banner,然后下载
②在resources文件夹下,即application.properties同目录,创建一个banner1.txt文件,将上述复制或下载的banner传入。
-
tomcat port号配置:
- 直接在application.properties里面写:
port=8081
即可。
- 直接在application.properties里面写:
原理初探
自动配置的原理:
pom.xml
- 核心依赖在parent父工程中:parent项目里中还有一个dependencies父项目,其包含了所有依赖。
- 依赖不需要指定版本号:因为有这些版本在父依赖仓库里全部配置了properties。(几乎包含所有需要的)
启动器(starter)
- springboot将功能相近的API,整合成一个启动包。如
spring-boot-starter-web
,他就会帮我们自动导入web环境所有的依赖。 - 我们需要相应功能,只需要指定相应启动器。(在官网可以查询:连接)
主程序(主启动类)
说明:springboot所有的自动配置,都在启动类中被扫描并加载:spring.factories
所有的自动配置类都在这里面。但是不一定生效,只有条件成立才会生效(导入了对应的start,有了对应的启动器,自动装配才会生效,才会配置成功)
大概流程:
1.springboot启动时,从类路径下 /META-INF/spring.factories
获取指定的配置信息list,及其中所有包名
2.将这些自动配置的类添加依赖(pom.xml中添加starter依赖),配置就会生效,进行自动配置。
3.以前我们需要配置的东西,现在springboot帮我们做了。
4.整合了javaEE、解决方案和自动配置的东西都在spring-boot-autoconfiguration-2.2.6.RELEASE.jar下
5.他会把所有需要导入的组件,以全限定类名的方式返回,这些组件就会被添加到容器中。
6.容器中也会存在非常多的xxxAutoConfiguration的类名,这些类给容器中导入了这个场景所需要的所有组件(@Bean返回值),并自动配置,免去我们手动配置文件的时间。
-
标注了
@SpringbootApplication
的类,作为应用的主入口。@SpringbootApplication
注解包含了多个注解,下面说其中两个:-
@SpringBootConfiguration
:-
@Configuration
:spring配置注解-
@Component
:说明其本质是组件类
-
-
-
@EnableAutoConfiguration
:自动配置-
@AotuComfiguration
:自动配置包-
@Import(AutoConfigurationPackages.Registrar.class)
:导入注册
-
-
@Import(AutoConfigurationImportSelector.class)
:导入选择器
-
-
-
main方法:
在main中,
SpringApplication.run(XXApplication.class,args)
,反射创建该类。
主启动类的运行分析(springApplication.run(..))
SpringApplication.run(MySpringBootApplication.class, args);
的四个职责:
判断应用的类型是普通的项目还是web项目
查找并加载所有可用初始化器,设置到initializers属性中
找出所有应用程序监听器,设置到listeners属性中
推断并设置main方法的定义类,找到运行的主类。
yaml语法
说明:springboot使用全局的配置文件,配置文件的名称固定:
-
application.properties
- 语法:key=value
-
application.yml
(*官方推荐)- 语法:key: 空格 value 如:
port: 8081
- 注意空格必须存在,格式是规定的。
- 语法:key: 空格 value 如:
职责:修改springboot自动配置的默认值,其已经在底层给我们自动配置了,我们可以通过设定值,来进行自定义。
基本语法:
#代表注释,yaml对空格要求严格。
#强大功能:可以注入到我们的配置类中
#普通的key-value
name: 老孙
#支持存放对象
student:
name: 老孙
age: 24
#行内写法
student: {name: MrSun,age: 24}
#数组
pets:
- cat
- dog
- pig
#数组行内写法
pets: [cat,dog,pig]
使用yaml对对象参数注入
.yml文件中:
person:
name: mySun
age: 24
sex: G
# birthday: 1996/4/6 其类注入失败,猜测是不能对该字符串类型,进行Date自动转换。
birthday: 1996-4-6
map: {k1: v1,k2: v2}
list:
- code
- music
- girl
dog:
name: 仔仔
age: 3
实体类中:
@Component
@ConfigurationProperties("person")
public class Person {
String name;
int age;
char sex;
Date birthday;
Map<String,Object> map;
List<String> list;
Dog dog;
...
}
说明:一般用于JavaConfig配置类里面。
@PropertySource
- 用properties也可以进行对象属性注入,但是更繁琐。
@PropertySource("classpath:custom.properties")
注解类,在类中,每个属性进行注释@Value("${name}")
。
-
yaml文件中,可以使用spring的EL表达式,如:
person: name: mySun.${random.int} //随机整数 age: 2${random.int} ... dog: ${person.hello:hello}_狗 //指定默认值形式,若hello存在,则结果:${person.hello}_狗 name: 仔仔 //如果不存在,则:hello_狗 age: 3
yaml和properties的区别
松散绑定:即yaml中的值,可以与实体类属性名字格式不同,如:last-name 和 lastName。其可以赋值成功
-
JSR303数据校验:在这个字段增加一层过滤器验证,验证合法性等。
格式:类前注释
@Validated
,然后变量前注释以下内容:
- 复杂类型封装:yaml可以封装对象
多环境配置、配置文件位置
说明:配置文件规定的几种位置,可以从SpringBoot官网Guide里找到,优先级渐低:
多环境配置:
在真实项目开发中,会有多种环境,如test、development等,springboot支持多环境配置,但默认读取application.properties
配置文件
激活其他环境配置文件:
- properties实现:
在主配置文件applicaiton.properties
中:键入:spring.profiles.active=test
,其就会选择application-test.properties
来运行。
-
yaml实现:(推荐)
直接将三个环境的配置,写在一个yaml中:
server: port: 8081 spring: profile: active: dev --- server: port: 8082 spring: profile: test --- server: port: 8083 spring: profile: dev
配置文件和spring.factories
spring.factories
spring.factories中,包含了多个配置环境,如Listeners、Processors等,每个配置环境包含了诸多相关配置类。
XXXproperties类:
我们在配置文件中自定义的字符串,如spring.mvc.dateFormat: yyyy-MM-dd
,其是更换(注入)了WebMvcProperties
属性类的默认值,该类主要供WebMvcAutoConfiguration
配置类使用。
意味我们在application.properties
、application.yaml
中写的属性,其必须已经由spring整合了默认配置类,否则并不会生效。
导入的每个(springboot已配置)依赖包,都有一个...properties类,我们更改application.yaml也就是更改其类属性。
了解的原因:
这样,我们能知道在配置文件中,我们能写什么东西,如下述具体配置类的实例中,其属性我们都可以指定,如其引用成员变量Encoding类:
我们可以在文件中编写:spring.http.encoding.XXX
配置encoding中的属性。
配置文件字段与Properties类映射
注解:@ConfigurationProperties
在配置类前注解该类(spring也是这样做的),然后value\prefix传入配置文件中的对应的字符串即可。如:
@ConfigurationProperties(prefix = "spring.mvc")
spring.factories位置:
2.2.6.RELEASE/spring-boot-autoconfigure-2.2.6.RELEASE.jar/META-INF/spring.factories
某个具体配置类实例:
下述是HttpEncodingAutoAconfiguration
的类体,其属于一个配置环境。
第一个注解:声明该类是配置类就不说了。
第二个注解:其自动配置属性,点进HttpProperties.class,其注解了@ConfigurationProperties
,如下
其是通过配置文件.yaml中的spring.http对应的值,给其属性(成员变量)进行自动注入。
第三~五个注解:决定该配置类是否生效:根据三个注解的条件成立与否。
@Conditional注解
查看所有生效、没生效、排除配置类
在配置文件application.xxx中输入:debug: true
。然后启动即可在console中看到。
自定义starter
步骤:
①创建XXXconfiguration类,
②创建XXXProperties类,
③将两者放入org.springframework.boot.autoconfigure包下。
SpringBoot web开发
说在前面:springboot帮我们配置了什么东西?我们能不能修改?可以修改哪些?能不能拓展?
- 上述都是可以的。
- xxxxAutoConfigurationxxx:自动配置类,可以像容器中自动配置Bean。
- xxxxProperties:自动配置类,装配配置文件中自定义的一些内容。
静态资源
使用以下方式处理静态资源:
webjars:百度搜,并去官网,可以找到很多的jar,并有依赖。将其导入pom.xml即可。然后就可以在浏览器中输入指定url,得到导入的webjars包的文件。
-
将资源放到指定位置:
源码中声明的classpath:
/**
、/resources
、/statis
(默认创建)、/public
。(优先级递减;classpath是默认创建的resources文件夹,application.yaml也是放在其内;)如在浏览器中输入:
localhost:8080/myjsp
,其会到上述四个目录下查找myjsp,当url存在目录时,也会递归搜寻目录。
templates目录
说明:对于该目录下的所有页面,只能通过我们的@Controller来进行跳转。(利用配置的视图解析器)
注意:需要模板引擎的支持,要导入thymeleaf依赖包。
自定义首页
将index.html
自定义文件放到资源目录下即可。
注意,若要放在/templates,即使用Controller来返回index,则需要先配置thymeleaf依赖。
自定义浏览器标签页图标
在最新版本好像不行了,在2.1.7版本是可以的:
①直接在/resources、/static、/public、/templates(需先如上调用thymeleaf)中的一个目录下,放一个favicon.ico图像即可。
②在application.yaml中:spring.mvc.favicon.enabled=false
;关闭默认图标
Thymeleaf模板引擎
模板引擎:
如jsp也是一个模板引擎,如下示意图:
补充:Thymeleaf模板引擎是SpringBoot推荐的。
导入配置:
所以需要我们手动导入thymeleaf依赖,可以在Spring官网ref文档查询
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
补充:可以去父项目dependencies里面看版本是不是比较旧,如果是,则需要在<properties>里面配置版本号。查找后我看到版本还是满新的,官方也就多出了一个snapshot版本。
使用thymeleaf
html中:
①导入thymeleaf命名空间。(thymeleaf官方文档):
<!DOCTYPE html>
<!-- 导入命名空间-->
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Good Thymes Virtual Grocery</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" media="all"
href="../../css/gtvg.css" th:href="@{/css/gtvg.css}" />
</head>
<body>
<p th:text="#{home.welcome}">Welcome to our grocery store!</p>
</body>
</html>
Thymeleaf语法
-
Simple expressions:
- Variable Expressions:
${...}
- Selection Variable Expressions:
*{...}
- Message Expressions:
#{...}
(国际化) - Link URL Expressions:
@{...}
- Fragment Expressions:
~{...}
- Variable Expressions:
-
Literals(字面值)
- Text literals:
'one text'
,'Another one!'
,… - Number literals:
0
,34
,3.0
,12.3
,… - Boolean literals:
true
,false
- Null literal:
null
- Literal tokens:
one
,sometext
,main
,…
- Text literals:
-
Text operations:
- String concatenation:
+
- Literal substitutions:
|The name is ${name}|
- String concatenation:
-
Arithmetic(算术) operations:
- Binary operators:
+
,-
,*
,/
,%
- Minus sign (unary operator):
-
- Binary operators:
-
Boolean operations:
- Binary operators:
and
,or
- Boolean negation (unary operator):
!
,not
- Binary operators:
-
Comparisons and equality:
- Comparators:
>
,<
,>=
,<=
(gt
,lt
,ge
,le
) - Equality operators:
==
,!=
(eq
,ne
)
- Comparators:
-
Conditional operators:
- If-then:
(if) ? (then)
- If-then-else:
(if) ? (then) : (else)
(*) - Default:
(value) ?: (defaultvalue)
- If-then:
-
Special tokens:
- No-Operation:
_
- No-Operation:
All these features can be combined and nested:
'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))
说明:
所有的html元素都可以被html接管,需要在标签对应属性中,添加th:
前缀,如要:
<div th:text="${msg}"></div>
注意:
只有属性标注了th:
,并在对应value中,才可以使用thymeleaf的语法,否则不生效。
对应属性的功能
Order | Feature | Attributes |
---|---|---|
1 | Fragment inclusion |
th:insert th:replace
|
2 | Fragment iteration | th:each |
3 | Conditional evaluation |
th:if th:unless th:switch th:case
|
4 | Local variable definition |
th:object th:with
|
5 | General attribute modification |
th:attr th:attrprepend th:attrappend
|
6 | Specific attribute modification |
th:value th:href th:src ...
|
7 | Text (tag body modification) |
th:text th:utext
|
8 | Fragment specification | th:fragment |
9 | Fragment removal | th:remove |
数组遍历语法
<!-- 第一种写法(建议),字面值即普通字符串用'',然后用+号连接 -->
<h4 th:each="fruit:${fruits}" th:text="${fruit}+':推荐写法'"></h4>
<!-- 第二种写法 -->
<!-- <h4 th:each="fruit:${fruits}">[[${fruit}]]:第二种写法</h4> -->
拓展springmvc
详细看官方文档:这里
步骤:
- ①创建自定义配置类,其实现
WebMvcConfigurer
接口。 - ②-1:可以直接重载该接口的方法,并编写自定义代码。
- ②-2:在配置类中创建想要自定义的mvc组件类,并实现其接口,如下的
ViewResolver
。 - ③将组件放入spring容器中。可以如下用@Bean方式,或者用BeanFactory等方式。
拓展视图解析器:
网站实现
前端模板
说明:可以直接下载网上的前端模板。
框架:bootstrap、Layui、semantic-ui、xadmin(专门后端)等,可以适当学一下这些模板知识:
- 栅格系统:将ui分成多少份
- 导航栏:
- 侧边栏:
- 表单:
首页配置
说明:如果是从网上下载模板,我们需要将静态资源导入我们的模板引擎,如Thymeleaf。
步骤:
①从网上、或者前端得到bootstrap模板,用于View视图
②导入thymeleaf
主要作用是以后计算我们修改了根目录,静态资源连接也不会影响,因为是绝对路径。而默认的html是相对路径。
③修改所有的静态资源(html)中部分元素的属性:(语法参考thymeleaf语法)
<link>
、<a>
的href
使用thymeleaf接管:如本地资源索引:
href="/../.."
→th:href="@{/../..}"
页面国际化(locale:地区化)
说明:最主要是提供页面的多种语言访问机制,根据传入的请求头的语言,一般是浏览器设置。或者也可以在页面添加语言按钮,再自定义LocaleResolver
进行处理。
步骤:
①对需要国际化页面,配置属性文件,在resources下建立i18n
目录。
②在主配置文件中添加:spring.messages.basename=i18n/login
③在前端切换语言标签中,将属性ref
修改,每个语言对应一个语言请求头(可以用url传递),如:zh_CN、en-US。
④自定义配置地区化解析器:
springboot会检查是否有自定义的LocaleResolver,如果有则使用该解析器,否则是默认解析器,其是按照浏览器发送的accept-language来进行处理,所以不支持多种语言切换,需要我们自己配置。
@Override
public Locale resolveLocale(HttpServletRequest request) {
System.out.println("resolverLocale执行了");
String lang = (String) request.getParameter("l");
Locale locale = Locale.getDefault();
if (!StringUtils.isEmpty(lang)) {
String[] ofLang = lang.split("_");
locale = new Locale(ofLang[0],ofLang[1]);
}
// TODO Auto-generated method stub
return locale;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
// TODO Auto-generated method stub
}
⑤将其添加到自定义的WebMvcConfiguration实现类中
//国际化:自定义本地化解析器
@Bean
public LocaleResolver localeResolver() {
return new MyLocaleResolver();
}
业务逻辑处理
ubuntu--springbootInstance01
说明:View上一个<a>连接,对应着一个Controller。该Controller可能会调用Service(其引用了dao),实现一个视图--数据库--视图的全程访问。
如:统计网页上,一个label对应着【员工信息】,点击这个label时,其会被服务器中对应Controller拦截,并调用对应Service组件,该组件又调用了DAO组件,实现对数据层的访问。
然后Controller处理结果,并返回字符串,让DispatcherServlet去将对应视图返回到浏览器。
数据库、安全相关
[JdbcTemplate + Druid 数据源](#JdbcTemplate + Druid 数据源)
整合JDBC
数据源选择
说明:现在最好的数据源:
Hikari:号称JavaWeb当前速度最快的数据源。相比传统的jdbc、c3p0、DBCP(数据库连接池)、tomcat等连接池更优秀。(springboot默认)
Druid:ali开源,集成了日志,易于获取数据库访问统计信息。
整合流程
①依赖:
<!-- 导入jdbc依赖,spring为我们提供了jdbcTemplate封装类,可以比原生jdbc更便捷 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
②Application配置文件:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/TestBase
username: sun
password: sunlin
③使用:
完成上述之后,可以直接使用了,jdbcTemplate对数据库具有不错的封装:
@Autowired
JdbcTemplate jdbcTemplate;
@Test
void JdbcTemplateTest() throws SQLException {
//spring提供的jdbcTemplate,非常简单的就完成了。
List<Map<String, Object>> resultList = jdbcTemplate.queryForList("select * from subjects;");
System.out.println(resultList);
}
原生jdbc:
@Autowired
DataSource dataSource;
void rawJdbcTest() throws SQLException {
//原生jdbc测试
//建立sql语句
String sqlString="select * from subjects;";
//从数据库得到连接
PreparedStatement ss = dataSource.getConnection().prepareStatement(sqlString);
//发送语句并接受结果
ResultSet rs = ss.executeQuery();
int i=0;
while(rs.next()) {
System.out.println("结果==>"+i+" "+rs.getInt("id"));
System.out.println("结果==>"+i+" "+rs.getInt("uid"));
System.out.println("结果==>"+i+" "+rs.getString("enjoy"));
System.out.println("结果==>"+i+" "+rs.getString("name"));
System.out.println("结果==>"+i+" "+rs.getInt("grade"));
i++;
}
ss.close();
JdbcTemplate + Druid 数据源
CSDN文章:比较完美的Druid+log4j2配置:比较好,完全配置,可以去看看。
①依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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-web</artifactId>
<exclusions>
<!--移除自带web日志管理 -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
②配置:
application.yaml:替换默认数据源:
spring:
datasource:
#尝试用阿里的Druid数据源,若没下面语句,则是使用默认的Hikari
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/TestBase?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
username: sun
password: sunlin
#下面的配置,是Druid超越其他数据源的优势:说明:filters:监控统计拦截器{stat:监控统计、log4j:日志记录、wall:防御sql注入},只需要配置即可生效。 log4j记得导入
filters: stat,wall,log4j2
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
#若需要配置其他数据源参数,无论是Hikari、Druid,都直接添加即可,如:
#initialSize: 5等等
说明:还可以配置一些数据源的参数,可以直接网上找,然后复制黏贴到配置文件:datasource下即可。
log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration status="WARN" monitorInterval="1800">
<Properties>
<!-- ==============================================公共配置============================================== -->
<!-- 设置日志文件的目录名称 -->
<property name="logFileName">IotEmLog</property>
<!-- 日志默认存放的位置,可以设置为项目根路径下,也可指定绝对路径 -->
<!-- 存放路径一:通用路径,window平台 -->
<property name="basePath">f:/Java/project/logs/${logFileName}</property>
<!-- 存放路径二:web工程专用,java项目没有这个变量,需要删掉,否则会报异常,这里把日志放在web项目的根目录下 -->
<!-- <property name="basePath">${web:rootDir}/${logFileName}</property> -->
<!-- 存放路径三:web工程专用,java项目没有这个变量,需要删掉,否则会报异常,这里把日志放在tocmat的logs目录下 -->
<!--<property name="basePath">${sys:catalina.home}/logs/${logFileName}</property>-->
<!-- 控制台默认输出格式,"%-5level":日志级别,"%l":输出完整的错误位置,是小写的L,因为有行号显示,所以影响日志输出的性能 -->
<property name="console_log_pattern">[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level]: %l - %m%n</property>
<!-- 日志文件默认输出格式,不带行号输出(行号显示会影响日志输出性能);%C:大写,类名;%M:方法名;%m:错误信息;%n:换行 -->
<!-- <property name="log_pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %C.%M - %m%n</property> -->
<!-- 日志文件默认输出格式,另类带行号输出(对日志输出性能未知);%C:大写,类名;%M:方法名;%L:行号;%m:错误信息;%n:换行 -->
<property name="log_pattern">[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level]: %C.%M[%L line] - %m%n</property>
<!-- 日志默认切割的最小单位 -->
<property name="every_file_size">20MB</property>
<!-- 日志默认输出级别 -->
<property name="output_log_level">DEBUG</property>
<!-- ===========================================所有级别日志配置=========================================== -->
<!-- 日志默认存放路径(所有级别日志) -->
<property name="rolling_fileName">${basePath}/all.log</property>
<!-- 日志默认压缩路径,将超过指定文件大小的日志,自动存入按"年月"建立的文件夹下面并进行压缩,作为存档 -->
<property name="rolling_filePattern">${basePath}/%d{yyyy-MM}/all-%d{yyyy-MM-dd-HH}-%i.log.gz</property>
<!-- 日志默认同类型日志,同一文件夹下可以存放的数量,不设置此属性则默认为7个,filePattern最后要带%i才会生效 -->
<property name="rolling_max">500</property>
<!-- 日志默认同类型日志,多久生成一个新的日志文件,这个配置需要和filePattern结合使用;
如果设置为1,filePattern是%d{yyyy-MM-dd}到天的格式,则间隔一天生成一个文件
如果设置为12,filePattern是%d{yyyy-MM-dd-HH}到小时的格式,则间隔12小时生成一个文件 -->
<property name="rolling_timeInterval">12</property>
<!-- 日志默认同类型日志,是否对封存时间进行调制,若为true,则封存时间将以0点为边界进行调整,
如:现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am...而不是7am -->
<property name="rolling_timeModulate">true</property>
<!-- ============================================Info级别日志============================================ -->
<!-- Info日志默认存放路径(Info级别日志) -->
<property name="info_fileName">${basePath}/info.log</property>
<!-- Info日志默认压缩路径,将超过指定文件大小的日志,自动存入按"年月"建立的文件夹下面并进行压缩,作为存档 -->
<property name="info_filePattern">${basePath}/%d{yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log.gz</property>
<!-- Info日志默认同一文件夹下可以存放的数量,不设置此属性则默认为7个 -->
<property name="info_max">100</property>
<!-- 日志默认同类型日志,多久生成一个新的日志文件,这个配置需要和filePattern结合使用;
如果设置为1,filePattern是%d{yyyy-MM-dd}到天的格式,则间隔一天生成一个文件
如果设置为12,filePattern是%d{yyyy-MM-dd-HH}到小时的格式,则间隔12小时生成一个文件 -->
<property name="info_timeInterval">1</property>
<!-- 日志默认同类型日志,是否对封存时间进行调制,若为true,则封存时间将以0点为边界进行调整,
如:现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am...而不是7am -->
<property name="info_timeModulate">true</property>
<!-- ============================================Warn级别日志============================================ -->
<!-- Warn日志默认存放路径(Warn级别日志) -->
<property name="warn_fileName">${basePath}/warn.log</property>
<!-- Warn日志默认压缩路径,将超过指定文件大小的日志,自动存入按"年月"建立的文件夹下面并进行压缩,作为存档 -->
<property name="warn_filePattern">${basePath}/%d{yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log.gz</property>
<!-- Warn日志默认同一文件夹下可以存放的数量,不设置此属性则默认为7个 -->
<property name="warn_max">100</property>
<!-- 日志默认同类型日志,多久生成一个新的日志文件,这个配置需要和filePattern结合使用;
如果设置为1,filePattern是%d{yyyy-MM-dd}到天的格式,则间隔一天生成一个文件
如果设置为12,filePattern是%d{yyyy-MM-dd-HH}到小时的格式,则间隔12小时生成一个文件 -->
<property name="warn_timeInterval">1</property>
<!-- 日志默认同类型日志,是否对封存时间进行调制,若为true,则封存时间将以0点为边界进行调整,
如:现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am...而不是7am -->
<property name="warn_timeModulate">true</property>
<!-- ============================================Error级别日志============================================ -->
<!-- Error日志默认存放路径(Error级别日志) -->
<property name="error_fileName">${basePath}/error.log</property>
<!-- Error日志默认压缩路径,将超过指定文件大小的日志,自动存入按"年月"建立的文件夹下面并进行压缩,作为存档 -->
<property name="error_filePattern">${basePath}/%d{yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log.gz</property>
<!-- Error日志默认同一文件夹下可以存放的数量,不设置此属性则默认为7个 -->
<property name="error_max">100</property>
<!-- 日志默认同类型日志,多久生成一个新的日志文件,这个配置需要和filePattern结合使用;
如果设置为1,filePattern是%d{yyyy-MM-dd}到天的格式,则间隔一天生成一个文件
如果设置为12,filePattern是%d{yyyy-MM-dd-HH}到小时的格式,则间隔12小时生成一个文件 -->
<property name="error_timeInterval">1</property>
<!-- 日志默认同类型日志,是否对封存时间进行调制,若为true,则封存时间将以0点为边界进行调整,
如:现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am...而不是7am -->
<property name="error_timeModulate">true</property>
<!-- ============================================控制台显示控制============================================ -->
<!-- 控制台显示的日志最低级别 -->
<property name="console_print_level">INFO</property>
</Properties>
<!--定义appender -->
<appenders>
<!-- =======================================用来定义输出到控制台的配置======================================= -->
<Console name="Console" target="SYSTEM_OUT">
<!-- 设置控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="${console_print_level}" onMatch="ACCEPT" onMismatch="DENY"/>
<!-- 设置输出格式,不设置默认为:%m%n -->
<PatternLayout pattern="${console_log_pattern}"/>
</Console>
<!-- ================================打印root中指定的level级别以上的日志到文件================================ -->
<RollingFile name="RollingFile" fileName="${rolling_fileName}" filePattern="${rolling_filePattern}">
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="${rolling_timeInterval}" modulate="${warn_timeModulate}"/>
<SizeBasedTriggeringPolicy size="${every_file_size}"/>
</Policies>
<!-- 设置同类型日志,同一文件夹下可以存放的数量,如果不设置此属性则默认存放7个文件 -->
<DefaultRolloverStrategy max="${rolling_max}" />
</RollingFile>
<!-- =======================================打印INFO级别的日志到文件======================================= -->
<RollingFile name="InfoFile" fileName="${info_fileName}" filePattern="${info_filePattern}">
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="${info_timeInterval}" modulate="${info_timeModulate}"/>
<SizeBasedTriggeringPolicy size="${every_file_size}"/>
</Policies>
<DefaultRolloverStrategy max="${info_max}" />
<Filters>
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
</RollingFile>
<!-- =======================================打印WARN级别的日志到文件======================================= -->
<RollingFile name="WarnFile" fileName="${warn_fileName}" filePattern="${warn_filePattern}">
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="${warn_timeInterval}" modulate="${warn_timeModulate}"/>
<SizeBasedTriggeringPolicy size="${every_file_size}"/>
</Policies>
<DefaultRolloverStrategy max="${warn_max}" />
<Filters>
<ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
</RollingFile>
<!-- =======================================打印ERROR级别的日志到文件======================================= -->
<RollingFile name="ErrorFile" fileName="${error_fileName}" filePattern="${error_filePattern}">
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="${error_timeInterval}" modulate="${error_timeModulate}"/>
<SizeBasedTriggeringPolicy size="${every_file_size}"/>
</Policies>
<DefaultRolloverStrategy max="${error_max}" />
<Filters>
<ThresholdFilter level="FATAL" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
</RollingFile>
<!--druid的日志记录追加器-->
<RollingFile name="druidSqlRollingFile" fileName="${basePath}/druid-sql.log"
filePattern="${basePath}/%d{yyyy-MM}/druid-sql-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<SizeBasedTriggeringPolicy size="100 MB"/>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingFile>
</appenders>
<!--定义logger,只有定义了logger并引入的appender,appender才会生效-->
<loggers>
<!-- 设置打印sql语句配置开始,以下两者配合使用,可以优化日志的输出信息,减少一些不必要信息的输出 -->
<!-- 设置java.sql包下的日志只打印DEBUG及以上级别的日志,此设置可以支持sql语句的日志打印 -->
<logger name="java.sql" level="DEBUG" additivity="false">
<appender-ref ref="Console"/>
</logger>
<!-- 设置org.mybatis.spring包下的日志只打印WARN及以上级别的日志 -->
<logger name="org.mybatis.spring" level="WARN" additivity="false">
<appender-ref ref="Console"/>
</logger>
<!-- 设置org.mybatis.spring包下的日志只打印WARN及以上级别的日志 -->
<logger name="org.springframework" level="WARN" additivity="false">
<appender-ref ref="Console"/>
</logger>
<!-- 设置org.mybatis.spring包下的日志只打印WARN及以上级别的日志 -->
<logger name="com.qfx.workflow.service" level="WARN" additivity="false">
<appender-ref ref="Console"/>
</logger>
<!-- 设置打印sql语句配置结束 -->
<!--记录druid-sql的记录-->
<logger name="druid.sql.Statement" level="debug" additivity="false">
<appender-ref ref="druidSqlRollingFile"/>
</logger>
<logger name="druid.sql.Statement" level="debug" additivity="false">
<appender-ref ref="druidSqlRollingFile"/>
</logger>
<!--建立一个默认的root的logger-->
<root level="${output_log_level}">
<appender-ref ref="RollingFile"/>
<appender-ref ref="Console"/>
<appender-ref ref="InfoFile"/>
<appender-ref ref="WarnFile"/>
<appender-ref ref="ErrorFile"/>
</root>
</loggers>
</configuration>
log4j.xml结尾
③使用:和之前一样,就可以直接使用了。非常轻松。
整合mybatis-spring-boot
步骤:
1:导入包:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
2:配置文件
- 首先是application.yaml,在其内部添加数据源。
- 然后配置mybatis的mapper(dao)接口别名、映射文件.xml位置(如果是纯注解则不需要)
3:编写sql,可以在对应类名的mapper.xml中,也可以直接在接口中。(对应接口类注释为@Repository、@Mapper
4:Controller调用Service层
5:Service业务层调用dao(Mapper)对象。
SpringSecutiry
说明:其是spring提供的一个髙定制性的认证和访问权限框架。
权限:
- 功能权限:如博客中,游客不能写博客,只有登录用户能写。
- 访问权限:如游客、普通用户不能访问后台。
- 菜单权限:
- ...
之前实现:一般用拦截器和过滤器。