SpringBoot——自学笔记
SpringBoot——自学笔记
学习视频B站狂神说:https://www.bilibili.com/video/BV1PE411i7CV
1、springboot自动装配原理浅理解
在编写springboot项目时,主项目会有一个@SpringBootApplication
,在这个注解的源码中包含了三个主要注解
@SpringBootConfiguration
通过源码得知他是一个@Configuration,所以也就是对spring原生注解的封装
@EnableAutoConfiguration
加上此注解会自动开启装配功能,也就是说spring会在自己的classpath(类路径)下找到所有配置的Bean进行装配
@ComponentScan
默认扫描的是与该类同级的类或者同级包下的所有类(这也就是为什么我们的项目代码建包或者建类需要在启动类的同级包下的原因
总的来说:
springboot自动装配原理利用了SpringFactoriesLoader来加载META-INF/spring.factories文件里的所有配置的EnableAutoConfiguration,通过start启动器(有一个注解叫:@ConditionalOnClass
)判断是否生效,最后确定要装配的类
精髓
1、SpringBoot启动会加载大量的自动配置类
2、我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;
3、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)
4、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;
**xxxxAutoConfigurartion:自动配置类;**给容器中添加组件
xxxxProperties:封装配置文件中相关属性;
2、主启动类的run()方法
run()
首先需要明白,该方法不仅仅只是一个简单的main方法,它启动时会开启一个服务!
@SpringBootApplication
public class SpringbootApplication {public static void main(String[] args) {SpringApplication.run(SpringbootApplication.class, args);}
}
SpringApplication.run分析
分析该方法主要分两部分,一部分是SpringApplication的实例化,二是run方法的执行;
SpringApplication
这个类主要做了以下四件事情:
1、推断应用的类型是普通的项目还是Web项目
2、查找并加载所有可用初始化器 , 设置到initializers属性中
3、找出所有的应用程序监听器,设置到listeners属性中
4、推断并设置main方法的定义类,找到运行的主类
3、YAML了解及使用
详情见博客:https://blog.csdn.net/weixin_46508271/article/details/118678699?spm=1001.2014.3001.5501
4、使用YAML注入配置文件
1、在springboot项目的resource目录新建文件application.yml
2、导入配置注解处理器依赖文件
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>
3、编写两个实体类
Dog:
@Component//注册bean
public class Dog {private String name;private String age;//省略构造函数,get、set方法等...
}
Person:
@Component//注册bean
public class Person {private String name;private String age;private Date birth;private Dog dog;private List<String> hobby;private Map<Object,Object> maps;//省略构造函数,get、set方法等...
}
4、编写application.yml配置文件
person:name: 小梁age: 20birth: 2021/07/12dog:name: 小梁的狗age: 3hobby:- 唱歌- 跳舞- rap- 篮球maps: {k1: v1, k2: v2}
5、注入到Person类中
@Component
@ConfigurationProperties(prefix = "person")
public class Person {private String name;private String age;private Date birth;private Dog dog;private List<String> hobby;private Map<Object,Object> maps;//省略构造函数,get、set方法等...
}
@ConfigurationProperties作用:
将配置文件中配置的每一个属性的值,映射到这个组件中;
告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定;
参数 prefix = “person” : 将配置文件中的person下面的所有属性一一对应;
6、测试
@SpringBootTest
class Springboot01ApplicationTests {@AutowiredPerson person;//将person自动注入进来@Testvoid contextLoads() {System.out.println(person.toString());//打印person的信息}
}
5、JSR303校验
1、导入依赖
2、在类上添加注解:@Validated
3、在需要进行数据规范的属性上进行注解标注(此处以邮箱格式为例)
@Component//注册bean
@ConfigurationProperties(prefix = "person")
@Validated//数据校验
public class Person {@Email//标明name属性的值必须为邮箱格式private String name;private String age;private Date birth;private Dog dog;private List<String> hobby;private Map<Object,Object> maps;//省略构造函数,get、set方法等...
}
输入格式错误时:
- Bean Validation 中内置的 constraint
- Hibernate Validator 附加的 constraint
6、多环境切换
profile是Spring对不同环境提供不同配置功能的支持,可以通过激活不同的环境版本,实现快速切换环境;
我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml , 用来指定多个环境版本;
6.1、properties的多文档块
application-test.properties 代表测试环境配置
application-dev.properties 代表开发环境配置
但是Springboot并不会直接启动这些配置文件,它默认使用application.properties主配置文件;
我们需要通过一个配置来选择需要激活的环境:
#比如在配置文件中指定使用dev环境,我们可以通过设置不同的端口号进行测试;
#我们启动SpringBoot,就可以看到已经切换到dev下的配置了;spring.profiles.active=dev
6.2、yaml的多文档块
server:port: 8081
#选择要激活那个环境块
spring:profiles:active: prod---
server:port: 8083
spring:profiles: dev #配置环境的名称---server:port: 8084
spring:profiles: prod #配置环境的名称
注意:如果yml和properties同时都配置了端口,并且没有激活其他环境 , 默认会使用properties配置文件的
6.2、配置文件加载优先级
springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件:
优先级1:项目路径下的config文件夹配置文件
优先级2:项目路径下配置文件
优先级3:资源路径下的config文件夹配置文件
优先级4:资源路径下配置文件
优先级由高到底,高优先级的配置会覆盖低优先级的配置;
7、静态资源处理
7.1、静态资源映射规则
ResourceProperties :
// 进入方法
public String[] getStaticLocations() {return this.staticLocations;
}
// 找到对应的值
private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
// 找到路径
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/","classpath:/resources/", "classpath:/static/", "classpath:/public/"
};
其中的classpath:
代表的就是我们的资源文件夹:resources
ResourceProperties 可以设置和我们静态资源有关的参数;这里面指向了它会去寻找资源的文件夹,即上面数组的内容。
所以我们可以得出结论,以下四个目录存放的静态资源可以被我们识别读取
"classpath:/META-INF/resources/"
"classpath:/resources/"
"classpath:/static/"
"classpath:/public/"
一般就存放在下面三个文件就行
8、首页处理
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,FormattingConversionService mvcConversionService,ResourceUrlProvider mvcResourceUrlProvider) {WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(), // getWelcomePage 获得欢迎页this.mvcProperties.getStaticPathPattern());welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));return welcomePageHandlerMapping;
}
继续深入:
private Optional<Resource> getWelcomePage() {String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());// ::是java8 中新引入的运算符// Class::function的时候function是属于Class的,应该是静态方法。// this::function的funtion是属于这个对象的。// 简而言之,就是一种语法糖而已,是一种简写return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
}
// 欢迎页就是一个location下的的 index.html 而已
private Resource getIndexHtml(String location) {return this.resourceLoader.getResource(location + "index.html");
}
欢迎页,静态资源文件夹下的所有 index.html 页面;被 /** 映射。
比如我访问 http://localhost:8080/ ,就会找静态资源文件夹下的 index.html
9、Thymeleaf模板引擎
SpringBoot推荐使用Thymeleaf模板引擎
9.1、引入Thymeleaf
Thymeleaf 官网:https://www.thymeleaf.org/
Thymeleaf 在Github 的主页:https://github.com/thymeleaf/thymeleaf
Spring官方文档:找到我们对应的版本
https://docs.spring.io/spring-boot/docs/2.5.0.RELEASE/reference/htmlsingle/#using-boot-starter
找到对应的依赖并导入:
<!--thymeleaf-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
9.2、使用Thymeleaf
在我们需要操作的html界面中添加命名空间xmlns:th="http://www.thymeleaf.org"
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>....
</head>
Thymeleaf基本语法
Selection Variable Expressions: *{...}:选择表达式:和${}在功能上是一样;
Message Expressions: #{...}:获取国际化内容
Link URL Expressions: @{...}:定义URL
Fragment Expressions: ~{...}:片段引用表达式
比如我们在controller层中写一个请求:
@Controller
public class MsgController {@RequestMapping("/test")public ModelAndView test(){ModelAndView mv = new ModelAndView("test");mv.addObject("msg","欢迎来到SpringBoot!");mv.addObject("users", Arrays.asList("小梁","大梁","老梁"));return mv;}
}
在前端界面接收:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>SpringBoot Test</title>
</head>
<body>
<div th:text="${msg}"></div>
<h3 th:each="user:${users}" th:text="${user}"></h3>
</body>
</html>
显示结果:
10、员工管理系统:准备工作
10.1、新建springboot项目
这里为了偷懒,导入一下lombok的依赖(如果第一次使用需要先安装插件)
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId>
</dependency>
10.2、导入静态资源
10.3、创建实体类
Department
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Department {private Integer id;private String department;
}
Employee
@Data
@NoArgsConstructor
public class Employee {private Integer id;private String name;private String email;private Integer gender;private Department department;private Date birth;//这里手写有参构造的原因是直接给birth初始值,省的后面还得去赋值public Employee(Integer id, String name, String email, Integer gender, Department department) {this.id = id;this.name = name;this.email = email;this.gender = gender;this.department = department;this.birth = new Date();}
}
10.4、编写dao
DepartmentDao
//部门表dao
@Repository
public class DepartmentDao {//模拟数据库中的数据private static Map<Integer, Department> departments = null;static {//创建一个部门表departments = new HashMap<Integer,Department>();departments.put(101,new Department(101,"教学部"));departments.put(102,new Department(102,"研发部"));departments.put(103,new Department(103,"运维部"));departments.put(104,new Department(104,"后勤部"));departments.put(105,new Department(105,"市场部"));}//查询所有部门信息public Collection<Department> getDepartments(){return departments.values();}//根据id查询部门信息public Department getDepartmentByID(Integer id){return departments.get(id);}}
EmployeeDao
//员工表dao
@Repository
public class EmployeeDao {//模拟数据public static Map<Integer,Employee> employees = null;//员工所属部门@Autowiredprivate DepartmentDao departmentDao;static {employees = new HashMap<Integer,Employee>();//创建员工表employees.put(1001,new Employee(1001,"AAA","123456@163.com",0,new Department(101,"教学部")));employees.put(1002,new Employee(1002,"BBB","456789@163.com",1,new Department(102,"研发部")));employees.put(1003,new Employee(1003,"CCC","789123@163.com",0,new Department(103,"运维部")));employees.put(1004,new Employee(1004,"DDD","123567@163.com",1,new Department(104,"后勤部")));employees.put(1005,new Employee(1005,"EEE","234678@163.com",0,new Department(105,"市场部")));}//主键自增public Integer initId = 1006;//增加员工public void add(Employee employee){if (employee.getId() == null){employee.setId(initId++);}employee.setDepartment(departmentDao.getDepartmentByID(employee.getDepartment().getId()));employees.put(employee.getId(),employee);}//查询所有员工信息public Collection<Employee> getEmployees(){return employees.values();}//通过ID查询员工信息public Employee getEmployeeByID(Integer id){return employees.get(id);}//通过ID删除员工public void del(Integer id){employees.remove(id);}
}
11、员工管理系统:首页实现
编写mvc配置类,我这里命名为:MyMVCConfig
@Configuration
public class MyMVCConfig implements WebMvcConfigurer {//修改首页配置@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/").setViewName("index");registry.addViewController("/index.html").setViewName("index");}
}
启动项目,访问localhost:8080 检查项目是否正常
建议配置一下项目路径:
在springboot的配置文件application.properties
中:
# 配置项目路径
server.servlet.context-path=/teng
这样的话访问项目欢迎界面:localhost:8080/teng
12、员工管理系统:国际化
1、新建一个名叫“i18n”的包,我们用来存放国际化配置,然后在这个包下,我们再创建几个properties的配置文件,用来配置语言,如图所示
2、给配置文件添加内容
3、在application.properties配置文件中添加
spring.messages.basename=i18n.login
4、修改index.html,按照配置的国际化参数都设置好
5、自定义配置,使我们页面中的中英文切换生效
5.1、先给两个按钮添加链接
5.2、编写MyLocaleResolver实现接口LocaleResolver,重写方法
public class MyLocaleResolver implements LocaleResolver {@Overridepublic Locale resolveLocale(HttpServletRequest request) {String l = request.getParameter("l");Locale locale = Locale.getDefault();if (!StringUtils.isEmpty(l)){String[] splits = l.split("_");locale = new Locale(splits[0],splits[1]);}return locale;}@Overridepublic void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {}
}
5.3、在MyMVCConfig中将MyLocaleResolver注入springboot中
@Bean
public LocaleResolver localeResolver(){return new MyLocaleResolver();
}
可能导致国际化不成功的问题:
1、
这个地方填入的是语言的种类,而不是配置文件名(比如"login_en_US.properties")!
2、application.properties配置文件是否正确配置了spring.messages.basename=i18n.login
3、在配置类中,标红处的名字必须是localeResolver
,因为spring会根据这个固定的名称去自动装配,如果改名了那spring自然无法识别!
13、员工管理系统:登录功能实现
1、编写登录请求
@Controller
public class LoginController {@RequestMapping("/user/login")//请求地址public ModelAndView login(String userName, String password, HttpSession session){ModelAndView mv = new ModelAndView();if (!StringUtils.isEmpty(userName) && password.equals("123456")){session.setAttribute("loginInfo",userName);//登录成功添加session信息mv.setViewName("redirect:/main.html");//登陆成功——>重定向到main.html}else {mv.addObject("msg","用户名或密码错误!");//错误提示mv.setViewName("index");}return mv;}
}
2、在MyMVCConfig
设置跳转界面
registry.addViewController("/main.html").setViewName("dashboard");
3、修改html表单提交请求
14、员工管理系统:登录拦截
1、编写拦截器MyHandlerInterceptor
//登录拦截器
public class MyHandlerInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {Object loginSession = request.getSession().getAttribute("loginInfo");if (loginSession == null){request.setAttribute("msg","没有权限,请先登录!");request.getRequestDispatcher("/index.html").forward(request,response);return false;}else {return true;}}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {HandlerInterceptor.super.afterCompletion(request, response, handler, ex);}
}
2、在MyMVCConfig中注册拦截器
//注册登录拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/","/user/login","/index.html","/css/**","/js/**","/img/**");
}
addPathPatterns()为拦截的界面
excludePathPatterns()为放行资源
展示员工列表、增加员工实现、修改员工信息略
15、员工管理系统:删除及404处理
16、整合JDBC使用
16.1、准备阶段
1、创建项目,导入依赖
2、编写application.yml配置文件,这里的连接对象以mybatis数据库为例
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/mybatis?useEncoding=true&characterEncoding=utf-8username: rootpassword: 123456
3、在测试类中进行简单测试
@SpringBootTest
class Springboot04JdbcApplicationTests {//DI注入数据源@AutowiredDataSource dataSource;@Testvoid contextLoads() throws SQLException {//打印默认数据源System.out.println(dataSource.getClass());Connection conn = dataSource.getConnection();System.out.println(conn);conn.close();}}
从控制台输出可知:在springboot中默认的数据源为:class com.zaxxer.hikari.HikariDataSource
HikariDataSource 号称 Java WEB 当前速度最快的数据源,相比于传统的 C3P0 、DBCP、Tomcat jdbc 等连接池更加优秀;
16.2、CRUD操作数据库
JDBCTemplate
JDBCTemplate是Spring对JDBC的封装,目的是使JDBC更加易于使用。JdbcTemplate是Spring的一部分。JdbcTemplate处理了资源的建立和释放。他帮助我们避免一些常见的错误,比如忘了总要关闭连接。他运行核心的JDBC工作流,如Statement的建立和执行,而我们只需要提供SQL语句和提取结果。
在JdbcTemplate中执行SQL语句的方法大致分为3类:
execute
:可以执行所有SQL语句,一般用于执行DDL语句。update
:用于执行INSERT
、UPDATE
、DELETE
等DML语句。queryXxx
:用于DQL数据查询语句。
编写JDBCController测试:
package com.teng.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;
import java.util.Map;@RestController
@RequestMapping("/jdbc")
public class jdbcController {@AutowiredJdbcTemplate jdbcTemplate;//查询所有用户@RequestMapping("/list")public List<Map<String,Object>> userList(){String sql = "select * from mybatis.user";return jdbcTemplate.queryForList(sql);}//增加用户@RequestMapping("add")public String addList(){String sql = "insert mybatis.user(id,name,pwd) values(5,'法外狂徒','123456')";jdbcTemplate.update(sql);return "addList-OK!";}//修改用户信息@RequestMapping("/update/{id}")public String updateList(@PathVariable("id")Integer id){String sql = "update mybatis.user set name=?,pwd=? where id ="+id;Object[] objects = new Object[2];objects[0]="麻六";objects[1]="147258";jdbcTemplate.update(sql,objects);return "updateList-OK!";}//删除用户@RequestMapping("/del/{id}")public String delUser(@PathVariable("id")int id){String sql = "delete from mybatis.user where id=?";jdbcTemplate.update(sql,id);return "deleteUser-OK!";}
}
17、整合Druid数据源
Druid
Java程序很大一部分要操作数据库,为了提高性能操作数据库的时候,又不得不使用数据库连接池。
Druid 是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0、DBCP 等 DB 池的优点,同时加入了日志监控。
Druid 可以很好的监控 DB 池连接和 SQL 的执行情况,天生就是针对监控而生的 DB 连接池。
Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。
Spring Boot 2.0 以上默认使用 Hikari 数据源,可以说 Hikari 与 Driud 都是当前 Java Web 上最优秀的数据源,我们来重点介绍 Spring Boot 如何集成 Druid 数据源,如何实现数据库监控。
17.1、配置数据源
1、导入依赖
<dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.6</version>
</dependency>
2、在配置文件中切换数据源并配置设置项
spring:datasource:druid:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/mybatis?useEncoding=true&characterEncoding=utf-8username: rootpassword: 123456#Spring Boot 默认是不注入这些属性值的,需要自己绑定#druid 数据源专有配置minIdle: 5maxActive: 20maxWait: 60000timeBetweenEvictionRunsMillis: 60000minEvictableIdleTimeMillis: 300000validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsepoolPreparedStatements: true#配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入#如果允许时报错 java.lang.ClassNotFoundException: org.apache.log4j.Priority#则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4jfilters: stat,wall,log4jmaxPoolPreparedStatementPerConnectionSize: 20useGlobalDataSourceStat: trueconnectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
3、导入log4j依赖项
<dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version>
</dependency>
4、编写log4j.properties
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
5、为 DruidDataSource 绑定全局配置文件中的参数,再添加到容器中,而不再使用 Spring Boot 的自动生成了;我们需要 自己添加 DruidDataSource 组件到容器中,并绑定属性
@Configuration
public class DruidConfig {//绑定配置文件@ConfigurationProperties(prefix = "spring.datasource.druid")//注意:prefix中的不能使用驼峰写法,必须全部小写public DataSource druidDataSource(){return new DruidDataSource();}
}
6、测试
@SpringBootTest
class Springboot04JdbcApplicationTests {//DI注入数据源@AutowiredDataSource dataSource;@Testvoid contextLoads() throws SQLException {//看一下默认数据源System.out.println(dataSource.getClass());//获得连接Connection connection = dataSource.getConnection();System.out.println(connection);DruidDataSource druidDataSource = (DruidDataSource) dataSource;System.out.println("druidDataSource 数据源最大连接数:" + druidDataSource.getMaxActive());System.out.println("druidDataSource 数据源初始化连接数:" + druidDataSource.getInitialSize());connection.close();}}
测试成功,参数生效
17.2、配置Druid数据源监控
Druid 数据源具有监控的功能,并提供了一个 web 界面方便用户查看,类似安装 路由器 时,人家也提供了一个默认的 web 页面。
在DruidConfig类中设置 Druid 的后台管理页面,比如 登录账号、密码等配置后台管理;
@Configuration
public class DruidConfig {//获取yml配置文件的配置@ConfigurationProperties(prefix = "spring.datasource")//将druid数据源注入ioc容器@Beanpublic DataSource druid(){return new DruidDataSource();}//配置Druid的监控//1、配置管理后台的Servlet@Beanpublic ServletRegistrationBean DruidServlet(){ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");Map<String,String> initParams = new HashMap<>();//druid后台登录的用户名initParams.put("loginUsername","admin");//druid后台登录的密码initParams.put("loginPassword","111111");//默认就是允许所有访问initParams.put("allow","");bean.setInitParameters(initParams);return bean;}//2、配置监控的filter@Beanpublic FilterRegistrationBean druidStatFilter(){FilterRegistrationBean bean = new FilterRegistrationBean();bean.setFilter(new WebStatFilter());Map<String,String> initParams = new HashMap<>();initParams.put("exclusions","*.js,*.css,/druid/*");bean.setInitParameters(initParams);bean.setUrlPatterns(Arrays.asList("/*"));return bean;}}
启动项目,访问地址:localhost:8080/druid/login.html
使用设置的账号密码登录
18、整合mybatis
1、新建springboot项目,勾选相关依赖,配置资源过滤
<resources><resource><directory>src/main/resources</directory><includes><include>**/*.properties</include><include>**/*.xml</include><include>**/*.yml</include></includes><filtering>true</filtering></resource>
</resources>
2、配置数据库连接信息
spring:datasource:druid:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/mybatis?useEncoding=true&characterEncoding=utf-8username: rootpassword: 123456#Spring Boot 默认是不注入这些属性值的,需要自己绑定#druid 数据源专有配置minIdle: 5maxActive: 20maxWait: 60000timeBetweenEvictionRunsMillis: 60000minEvictableIdleTimeMillis: 300000validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsepoolPreparedStatements: true#配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入#如果允许时报错 java.lang.ClassNotFoundException: org.apache.log4j.Priority#则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4jfilters: stat,wall,log4jmaxPoolPreparedStatementPerConnectionSize: 20useGlobalDataSourceStat: trueconnectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
mybatis:type-aliases-package: com.teng.entity #别名mapper-locations: classpath:mapper/*.xml #mapper映射
3、搭建实体类User
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private int id;private String name;private String password;
}
4、编写UserMapper
@Mapper
@Repository
public interface UserMapper {List<User> getUsers();User getUserByID(@Param("id") int id);int updateUser(@Param("id") int id);int insertUser(User user);int deleteUser(@Param("id") int id);
}
5、编写UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.teng.mapper.UserMapper"><select id="getUsers" resultType="user">select * from mybatis.user;</select><select id="getUserByID" resultType="user">select * from mybatis.user where id=#{id};</select><update id="updateUser">update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id};</update><insert id="insertUser" parameterType="user">insert into mybatis.user(id, name, pwd)values (#{id},#{name},#{pwd});</insert>
</mapper>
6、编写UserService
public interface UserService {List<User> getUsers();User getUserByID(int id);int updateUser(int id);int insertUser(User user);int deleteUser(int id);
}
7、编写UserServiceImpl
@Service
public class UserServiceImpl implements UserService{@AutowiredUserMapper userMapper;@Overridepublic List<User> getUsers() {return userMapper.getUsers();}@Overridepublic User getUserByID(int id) {return userMapper.getUserByID(id);}@Overridepublic int updateUser(int id) {return userMapper.updateUser(id);}@Overridepublic int insertUser(User user) {return userMapper.insertUser(user);}@Overridepublic int deleteUser(int id) {return userMapper.deleteUser(id);}
}
8、编写UserController
@RestController
public class UserController {@AutowiredUserMapper userMapper;@RequestMapping("/list")public List<User> getUsers(){return userMapper.getUsers();}
}
整个项目结构:
19、SpringSecurity的简单使用
SpringSecurity简介
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
记住几个类:
- WebSecurityConfigurerAdapter:自定义Security策略
- AuthenticationManagerBuilder:自定义认证策略
- @EnableWebSecurity:开启WebSecurity模式
Spring Security的两个主要目标是 “认证” 和 “授权”(访问控制)。
“认证”(Authentication)
身份验证是关于验证您的凭据,如用户名/用户ID和密码,以验证您的身份。
身份验证通常通过用户名和密码完成,有时与身份验证因素结合使用。
“授权” (Authorization)
授权发生在系统成功验证您的身份后,最终会授予您访问资源(如信息,文件,数据库,资金,位置,几乎任何内容)的完全权限。
这个概念是通用的,而不是只在Spring Security 中存在。
19.1、环境准备
1、新建一个springboot项目,引入web和thymeleaf依赖
2、导入静态资源文件
3、编写RouterController
package com.teng.controller;import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpSession;@Controller
public class RouterController {@RequestMapping({"/","/index"})public String index(){return "index";}@RequestMapping("/toLogin")public String toLogin(){return "views/login";}@RequestMapping("/level1/{id}")public String level1(@PathVariable("id")int id){return "views/level1/"+id;}@RequestMapping("/level2/{id}")public String level2(@PathVariable("id")int id){return "views/level2/"+id;}@RequestMapping("/level3/{id}")public String level3(@PathVariable("id")int id){return "views/level3/"+id;}
}
19.2、SpringSecurity的使用
1、引入依赖文件
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency><dependency><groupId>org.thymeleaf.extras</groupId><artifactId>thymeleaf-extras-springsecurity5</artifactId><version>3.0.4.RELEASE</version>
</dependency>
2、新建SecurityConfig类
package com.teng.config;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;@EnableWebSecurity //开启WebSecurity模式
public class SecurityConfig extends WebSecurityConfigurerAdapter {//权限管理@Overrideprotected void configure(HttpSecurity http) throws Exception {//定制请求规则http.authorizeRequests().antMatchers("/").permitAll() //首页所有人可以访问.antMatchers("/level1/**").hasRole("vip1").antMatchers("/level2/**").hasRole("vip2").antMatchers("/level3/**").hasRole("vip3");//定制登录页http.formLogin().usernameParameter("username").passwordParameter("password").loginPage("/toLogin").loginProcessingUrl("/login");//开启注销功能,注销成功后来到首页http.csrf().disable();//关闭csrf功能:跨站请求伪造,默认只能通过post方式提交logout请求http.logout().logoutSuccessUrl("/");//记住我http.rememberMe().rememberMeParameter("remember");}//认证规则//可以在内存中自定义,也可以从数据库中拿取数据@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())//passwordEncoder密码加密规则,spring security推荐BCrypt加密规则.withUser("xiaoliang").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2")//xiaoliang用户拥有vip1和vip2的权限.and().withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3").and().withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip3");}
}
3、前端界面设置
引入命名空间
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
这里主要展示登录注销,其他的进行类似设置
<!--登录注销-->
<div class="right menu"><!--如果未登录--><div sec:authorize="!isAuthenticated()"><a class="item" th:href="@{/toLogin}"><i class="address card icon"></i> 登录</a></div><!-- 如果已经登录--><div sec:authorize="isAuthenticated()"><a class="item">用户名:<span sec:authentication="name"></span></a></div><div sec:authorize="isAuthenticated()"><a class="item" th:href="@{/logout}"><i class="iconfont icon-log-out"></i> 注销</a></div>
</div>
这里的sec:authorize="!isAuthenticated()"
为条件判断,如果成立则显示对应的div块,sec:authentication="name"
提取登录用户的信息
4、测试
首页:
点击登录时弹出的登录页:
填写用户信息后展示的首页:
登录账户为“xiaoliang”,因为只给该用户授予了vip1和vip2的权限,所以level3模块不显示!
21、邮件任务
1、引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId>
</dependency>
2、编写application.properties文件
spring.mail.username=1208805413
spring.mail.password=wdxjddcitclubaei
spring.mail.host=smtp.qq.com
spring.mail.properties.mail.smtp.ssl.enable=true
3、装配JavaMailSenderImpl
@Autowired
JavaMailSenderImpl mailSender;
4、测试简单邮件任务和复杂邮件任务
package com.teng;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;@SpringBootTest
class Springboot09AsyncApplicationTests {@AutowiredJavaMailSenderImpl mailSender;@Testvoid contextLoads() {//简单邮件SimpleMailMessage mailMessage = new SimpleMailMessage();mailMessage.setFrom("1208805413@qq.com");mailMessage.setTo("1208805413@qq.com");mailMessage.setSubject("测试-简单的邮件发送功能");mailMessage.setText("buling~");mailSender.send(mailMessage);}@Testvoid contextLoads01() throws MessagingException {//复杂邮件发送功能MimeMessage mimeMessage = mailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);helper.setFrom("1208805413@qq.com");helper.setTo("1208805413@qq.com");helper.setSubject("测试-复杂的邮件发送功能");helper.setText("<p style='color:red'>这是一行有颜色的文本段落</p>",true);//发送附件helper.addAttachment("18计算机四班.xlsx",new File("D:\\ssh\\18计算机四班.xlsx"));mailSender.send(mimeMessage);}}
22、定时任务
1、在主启动类上添加注解
@EnableScheduling //开启基于注解的定时任务
2、测试,编写ScheduledService
@Service
public class ScheduledService {//秒 分 时 日 月 周几//0 * * * * MON-FRI//注意cron表达式的用法;@Scheduled(cron = "0/2 * * * * ?")public void hello(){System.out.println("定时任务已发送!");}
}
常用表达式:
1)0/2 * * * * ? 表示每2秒 执行任务
(1)0 0/2 * * * ? 表示每2分钟 执行任务
(1)0 0 2 1 * ? 表示在每月的1日的凌晨2点调整任务
(2)0 15 10 ? * MON-FRI 表示周一到周五每天上午10:15执行作业
(3)0 15 10 ? 6L 2002-2006 表示2002-2006年的每个月的最后一个星期五上午10:15执行作
(4)0 0 10,14,16 * * ? 每天上午10点,下午2点,4点
(5)0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时
(6)0 0 12 ? * WED 表示每个星期三中午12点
(7)0 0 12 * * ? 每天中午12点触发
(8)0 15 10 ? * * 每天上午10:15触发
(9)0 15 10 * * ? 每天上午10:15触发
(10)0 15 10 * * ? 每天上午10:15触发
(11)0 15 10 * * ? 2005 2005年的每天上午10:15触发
(12)0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发
(13)0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发
(14)0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
(15)0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发
(16)0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44触发
(17)0 15 10 ? * MON-FRI 周一至周五的上午10:15触发
(18)0 15 10 15 * ? 每月15日上午10:15触发
(19)0 15 10 L * ? 每月最后一日的上午10:15触发
(20)0 15 10 ? * 6L 每月的最后一个星期五上午10:15触发
(21)0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最后一个星期五上午10:15触发
(22)0 15 10 ? * 6#3 每月的第三个星期五上午10:15触发
23、热部署
1、引入devtools依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional>
</dependency>
2、打开setting设置——Build、Execution、Deployment——Compiler——勾选Build project automatically
3、使用ctrl+shift+alt+/,在弹出来的消息框中选择Register,找到wen.app.running,勾选Value
SpringBoot——自学笔记相关推荐
- SpringBoot使用笔记
其实也是参考官方的:http://spring.io/guides/gs/rest-service/ ,在官方代码基础上加入了很多实用的东西,比如运行环境启动命令等等. 官方文档:http://doc ...
- 字节跳动大佬的Python自学笔记.pdf
1. 字节跳动大佬的Python自学笔记 这是我的一个朋友自学资料包,通过这个资料包自学拿到了字节跳动的Offer, 下面是他之前入门学习Python时候的学习资料,非常全面,从Python基础.到w ...
- JAVA自学笔记07
JAVA自学笔记07 1.构造方法 1) 例如:Student s = new Student();//构造方法 System.out.println(s);// Student@e5bbd6 2)功 ...
- MySQL自学笔记2--select的5个子句
MySQL自学笔记 使用的MySQL自带命令客户端,其中具体的操作是在自建的数据库下room303表中进行的,表中的列有:id.name.age.email.tel.salary.riqi.class ...
- springboot学习笔记:12.解决springboot打成可执行jar在linux上启动慢的问题
springboot学习笔记:12.解决springboot打成可执行jar在linux上启动慢的问题 参考文章: (1)springboot学习笔记:12.解决springboot打成可执行jar在 ...
- SpringBoot学习笔记(3):静态资源处理
SpringBoot学习笔记(3):静态资源处理 在web开发中,静态资源的访问是必不可少的,如:Html.图片.js.css 等资源的访问. Spring Boot 对静态资源访问提供了很好的支持, ...
- JAVA自学笔记24
JAVA自学笔记24 1.能使用同步代码块就使用同步代码块,除非锁对象是this,就可以考虑使用同步方法.静态方法的锁是类的字节码对象. 2.JDK5新特性 1)接口Lock void Lock()/ ...
- 怎么用vc采集ni卡数据_SystemLink自学笔记(6):SystemLink架构和数据服务
1. SystemLink架构和数据服务 1.1. 架构和特点 现在在对SystemLink的功能有了一个大概的了解后,可以进一步从它的整体架构学习这门新技术了.NI官网给出了白皮书,原文是英文资料, ...
- springboot学习笔记(五)
一丶注值方式 1.在application.properties文件中注值 首先我们将application.yml中的学生名字和年龄给注释掉,来验证在applic.properties的注值方式. ...
- JAVA自学笔记22
JAVA自学笔记22 1.操作基本数据类型的流 DataInputStream DataOutputStream 数据输出流允许应用程序以适当方式将基本的Java数据类型写入输出流中.然后,应用程序可 ...
最新文章
- 引入三方库_关于使用第三方库、代码复用的一些思考
- 交换机复习笔记 广播风暴抑制
- 使用redisson时关于订阅数的问题
- 【js】版本号对比处理方案
- redis cluster配置文件和集群状态详解
- mathematica在linux上运行,Mathematicamatlab的linux版的安装
- android layoutparams,Android LayoutParams用法解析
- 【New Feature】阿里云OSS同城区域冗余存储重磅发布,提供云上同城容灾服务能力!...
- 浏览器UI线程更新机制
- kingroot android 7,KingRoot全球实现Android 7.0一键 Root
- vue 直接访问静态图片_vue本地静态图片的路径问题解决方案
- 虚拟存储器和cache的异同
- 分类常用的神经网络模型,典型神经网络模型包括
- Python 机器学习实战 —— 监督学习(上)
- make错误 redis6_redis安装make失败,make[1]: *** [adlist.o] Error 127....
- 【04】制作一个鸿蒙应用-【先写一下最基本的前端代码】-优雅草科技伊凡
- 利用twitter官网提供的api 及tweepy库 爬取tweets
- 如何去除win10此电脑(这台电脑)首页的六个文件夹?
- 电脑上写一天工作汇报表时用哪个办公便签软件?
- 4款不错的UI设计软件推荐