SpringBoot-jar:内嵌tomcat
服务越来越多:springcloud
约定大于配置的核心思想,核心:自动装配,同时集成了大量第三方库配置。
优点:更快入门,开箱即用,内嵌容器简化web,没有冗余代码和很多xml配置
微服务:是一种架构风格,在开发一个应用的时候,这个应用必须构建成一系列小服务的组合,可以通过http和rpc的方式进行通信。把每个功能元素独立出来,把独立出来的功能元素动态组合,需要的功能元素采取组合。微服务架构是对功能元素进行赋值,而没有对整个应用进行复制。
1.直接在官网下载,导入idea
2.直接idea创建一个springboot项目
程序主入口
@SpringBootApplication
public class HelloApplication {
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class, args);
}
}
此注解包含:
@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan
所有的spingboot依赖都是使用这个开头的spring-boot-starter
原理:
pom.xml:
1 .spring-boot-dependencies :父工程中,存放了核心依赖,统一进行了版本管理
2.自动配置了资源过滤
3.在写或者引入一些springBoot依赖的时候,不需要指定版本,因为有这些版本仓库
启动器:
4.启动器 :springboot的启动场景 sprign-boot-starter-web,就会帮我们自动导入web环境所有的依赖
5.会将所有的功能场景都会变成一个一个的启动器
6.我们要使用什么功能,就只需要找到对应的启动器就可以了 starter
主程序:
//标注这个类是一个SpringBoot的应用 启动类下所有的资源被注入
@SpringBootApplication
public class HelloWorldApplication {
public static void main(String[] args) {
//将springboot应用类启动 反射
SpringApplication.run(HelloWorldApplication.class, args);
}
}
注解:
@SpringBootConfiguration
@Configuration :Spring配置类
@Component :说明这也是一个spirng的组件
@EnableAutoConfiguration : 自动配置
@AutoConfigurationPackage :自动配置包
@Import({Registrar.class}) : 自动配置 `包注册`
@Import({AutoConfigurationImportSelector.class})
//获取所有的配置
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
获取候选的配置
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
return configurations;
}
META-INF/spring.factories:自动配置的核心文件
Properties properties = PropertiesLoaderUtils.loadProperties(resource); 所有的资源加载到配置类中

@ConditionalOnClass 在自动配置的类中有这个注解,会去判断条件,条件成立才会加载此类,这也是为什么自动配置了很多资源,但是依然需要加starter依赖,某些资源才能使用,而不是所有的类都加载进去

结论:所有自动配置都是在启动的时候,扫描并加载;spring.factories所有的自动配置类都在这里,但是不一定生效,要判断条件是否成立,只要导入了对应的starter,就有了对应的启动器了,有了启动器我们的自动装配就会生效,然后配置成功。
1.启动的时候,从类路径下/META-INF/spring.factories获取指定的值
2.将这些自动配置的类导入容器,自动配置就会生效,帮我们自动配置(类上也有@ConditionalOnClass)
3.以前我们需要配置的东西,springboot帮我们做了
4.整合javaEE,解决方案和自动配置的东西都在spring-boot-autoconfigure-2.6.3.jar包下
5.它会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器
6.容器中也会存在多的***AutoConfiguration的文件,就是这些类给容器中导入了这个场景需要的所有组件,@Configuration,JavaConfig @Bean
7.免去了我们手动编写配置文件的工作
全面接管SpringMVC的配置
自定义配置的实现
#配置文件能写什么?---spring.factories 的联系 spring: mvc: format: date: dd/MM/yyyy dispatch-options-request: true #在配置文件中能配置的东西,一定会有 xxxAutoConfiguration 自动装配,默认值为 xxxProperties 文件 #可以和配置 文件绑定,所以我们就可以使用自定义的配置了 #打印日志,自动配置类已经启动并且已经生效的 和没匹配成功的 debug: true

-
SpringBoot启动会加载大量的自动配置类
-
我们需要的功能有没有在SpringBoot默认写好的自动配置类当中
-
我们再来看这个自动配置类中到底配置了哪些组件,存在则不需要手动配置
-
给容器中自动配置类添加组件的时候,会从properties类中获取某些属性,我们只需要在配置文件中指定这些属性的值即可;
xxxAutoConfiguration:自动配置类,给容器中添加组件
xxxProperties:封装配置文件中的相关属性
springboot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(如果用户自己配置@bean),就用用户配置的(比如yml文件),如果没有就用自动配置的,如果有些组件可以存在多个,比如我们的mvc视图解析器,就将用户自定义的和默认的组合起来。
主启动类怎么运行? SpringApplication.run()
SpringApplication.run(HelloWorldApplication.class, args);
-
推断应用类型是否为WEB
-
加载所有可用初始化器
-
设置所有可用程序监听器
-
推断并设置main方法的定义类,找到运行的主类
配置文件 可修改SpringBoot自动配置的一些默认值
SpringBoot使用一个全局的配置文件,配置文件名称是固定的,如果两种同时存在,properties会后加载,覆盖yaml文件的内容
application.properties (官方不建议用)语法结构 key=value 层级结构不明显
application.yaml 语法结构 key:空格value 还能存对象 空格来控制层级
server:
port: 8081
#对象
student:
name: jack
age: 3
#行内写法
students: {name: jack,age: 3}
#数组
pets:
- cat
- dog
#数组行内写法
pet: [cat,dog,pig]
可以给实体类赋值 一般用在配置类中,让一个类和一个文件绑定在一起;
也有松散绑定,yml中写last-name,这个和实体类的lastName是一样的,-后面跟着的字母默认是大写的,这就是松散绑定。
@ConfigurationProperties 将配置文件中配置的每一个属性的值,映射到这个组件中,告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定,参数prefix=" ",可以用于配置类中
@Value("旺财")
private String name;
@Value("3")
private Integer age;
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
person:
name: jack
age: ${random.uuid}
happy: false
birth: 2022/02/22
maps: {k1: v1,k2: v2}
hello: lala
lists:
- cod
- music
- girl
#springEL表达式的运用,随机占位 及 判断设定
#如果hello存在 就取person中hello的值+旺财 如果不存在就取hello+旺财
dog:
name: ${person.hello:hello}旺财
age: 3
也可以自己写配置文件指定路径加载
//加载指定的配置文件
@PropertySource(value="calsspath:jack.properties")
public class Person {
//spring的EL表达式取出配置文件的值
@Value("${name}")
private String name;
private Integer age;
private Boolean happy;
yaml 可以松散绑定
dog: first-name: tom age: 18
@ConfigurationProperties(prefix = "dog")
public class Dog {
private String firstName;
private Integer age;
JSR303数据校验 @Validated
//数据校验
@Validated
public class Person {
@NotNull
private String name;
private String age;

配置文件的位置及优先级

多环境配置
server: port: 8080 #激活dev版本 spring: profiles: active: dev --- server: port: 8081 spring: profiles: dev --- server: port: 8082 spring: profiles: test
WEB项目
需要解决问题:
1.导入静态资源 2,首页 3.模板引擎Thymeleaf 4.装配扩展SpringMVC 5.具体业务 6.拦截器
7.国际化
静态资源导入
1.去webjars统一管理,导入依赖即可使用,通过8080/webjars/资源名 也可访问
2 在resources目录下可多再建public resources文件夹来存放静态资源,直接/1.html即可访问,resources目录下的优先级最高>static(默认)>public

一般public放公共资源,resources放一些文件,static静态资源。 如果再yml文件中自己配置了静态资源路径,则自带的静态资源路径会失效。只要在资源目录下index命名的首页文件,就能被访问。
首页的controller跳转
//在templates目录下的所有页面,只能通过controller来跳转!
//这个需要模板引擎的支持!需要多导一个依赖
@Controller
public class IndexController {
@RequestMapping("/index")
public String index(){
return "index";
}
}
模板引擎thymleaf
作用:写一个页面模板,比如有些值是动态的,我们歇一歇表达式,组装一些数据,我们把这些数据找到,然后把这个模板和数据交给模板引擎,模板引擎会按照我们这个数据帮你把表达式解析,填充到我们指定的位置
导入依赖
<!--导入thymleaf依赖 我们都是基于3.x开发--> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-java8time</artifactId> </dependency>
肯定存在一个properties的相关的自动配置类
@ConfigurationProperties(
prefix = "spring.thymeleaf"
)
public class ThymeleafProperties {
private static final Charset DEFAULT_ENCODING;
public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";
private boolean checkTemplate = true;
private boolean checkTemplateLocation = true;
private String prefix = "classpath:/templates/";
private String suffix = ".html";
private String mode = "HTML";
private Charset encoding;
private boolean cache;
@Controller
public class HelloController {
@GetMapping("/test")
public String hello(Model model){
model.addAttribute("msg","<h2>helloThymeleaf</h2>");
return "test";
}
}
可直接跳转到templates文件夹下的 test命名的html页面
需要在html中导入约束
<html xmlns:th="http://www.thymeleaf.org">
表达式
<span th:text="${today}">
-
Simple expressions:
//普通变量
-
Variable Expressions:
${...} -
Selection Variable Expressions:
*{...}//取国际化消息
-
Message Expressions:
#{...}//取url
-
Link URL Expressions:
@{...}//如果是一些片段表达式
-
Fragment Expressions:
~{...}
-
-
Literals(字面量)
//文本 单引号
-
Text literals:
'one text','Another one!',…//数字直接写
-
Number literals:
0,34,3.0,12.3,…//boolean值
-
Boolean literals:
true,false//空
-
Null literal:
null//标识符
-
Literal tokens:
one,sometext,main,…
-
-
Text operations:(文本操作)
-
String concatenation:
+ -
Literal substitutions:
|The name is ${name}|
-
-
Arithmetic operations:(数学运算)
-
Binary operators:
+,-,*,/,% -
Minus sign (unary operator):
-
-
-
Boolean operations:(布尔表达式)
-
Binary operators:
and,or -
Boolean negation (unary operator):
!,not(取反)
-
-
Comparisons and equality:(比较运算)
-
Comparators:
>,<,>=,<=(gt,lt,ge,le) -
Equality operators:
==,!=(eq,ne)
-
-
Conditional operators:(三元运算)
-
If-then:
(if) ? (then) -
If-then-else:
(if) ? (then) : (else) -
Default:
(value) ?: (defaultvalue)
-
-
Special tokens: 分割表达式
-
No-Operation:
_
-
基础语法
| 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 |
例子:
<body>
<!--所有的html元素都可以被thymeleaf替换接管 th:元素-->
<div th:text="${msg}"></div>
<!--会将信息中的标签转译 不是纯文本信息了-->
<div th:utext="${msg}"></div>
</body>
</html>
遍历:
@Controller
public class HelloController {
@GetMapping("/test")
public String hello(Model model){
model.addAttribute("msg","<h2>helloThymeleaf</h2>");
//测试模板遍历,在集合中放两个元素
model.addAttribute("users", Arrays.asList("jack","tom"));
return "test";
}
}
<!--将users里面的内容遍历出来放在user里,文本显示出来 两种写法均可以-->
<h3 th:each="user:${users}" th:text="${user}"></h3>
<h3 th:each="user:${users}" >[[ ${user} ]]</h3>
扩展装配MVC
//写在config包下
//如果想定制化功能,重写这个组件,然后交给springboot 会自动装配
//通过这个类 扩展mvc 配置 要实现WebMvcConfigurer
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
//ViewResolver 实现了视图解析器接口的类,就可以看做视图解析器 我们去接管视图解析器 重写他的方法resolveViewName
@Bean
public ViewResolver MyViewResolver() {
return new MyViewResolver();
}
//写静态内部类自定义一个视图解析器
public static class MyViewResolver implements ViewResolver {
@Override
public View resolveViewName(String viewName, Locale locale) throws Exception {
return null;
}
}
}
视图解析重写
//如果我们要扩展springmvc 官方建议我们这样去做 不能加@EnableWebMvc
//@EnableWebMvc 导入了一个类 DelegatingWebMvcConfiguration:从容器中获取所有的webmvcconfig
//会导致mvc自动配置崩盘 ,因为Condition判定 已经存在,不满足自动配置的条件
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
//扩展 视图跳转
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//添加视图控制 这个路径可以直接跳转到test.html页面
registry.addViewController("/xie").setViewName("test");
}
}
在springboot中,有非常多的xxxx Configuration帮助我们进行扩展配置,需要注意!
国际化


登录拦截器
@Controller
public class LoginController {
@RequestMapping("/login")
public String login(
@RequestParam("username")String username,
@RequestParam("password")String password,
Model model, HttpSession session){
//具体的业务
if(!StringUtils.isEmpty(username) && "123456".equals(password)){
session.setAttribute("loginUser",username);
return "redirect:/main.html";
}else{
//告诉用户,你登录失败了
model.addAttribute("msg","用户名或密码错误!");
return "index";
}
}
//登录拦截器
@Configuration
public class LoginHandlercepter implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//登录成功之后应该有用户的session
Object loginUser = request.getSession().getAttribute("loginUser");
//没有登录
if(loginUser==null){
request.setAttribute("msg","没有权限请先登录!");
request.getRequestDispatcher("/index.html").forward(request,response);
return false;
}else{
return true;
}
}
mvc的扩展配置里面需要将拦截器的拦截路径进行设定,排除不需要拦截的页面(比如一些静态资源)

导入druid依赖后配置
特点是日志监控,用了log4j,还需要导入log4j的依赖;可以自定义配置;防御sql注入

自定义配置,绑定配置文件

增加后台监控功能页面


某些请求过滤掉,不需要监控统计

整合Mybatis
整合包
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.1</version> </dependency>
spring.datasource.username=root spring.datasource.password=root spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
测试是否连接上
@SpringBootTest
class MyBatisApplicationTests {
@Autowired
DataSource dataSource;
@Test
void contextLoads() throws SQLException {
System.out.println(dataSource.getClass());
System.out.println(dataSource.getConnection());
}
}
//class com.zaxxer.hikari.HikariDataSource
//HikariProxyConnection@1829313709 wrapping com.mysql.cj.jdbc.ConnectionImpl@7c663eaf
建实体类pojo,或者 entity
配置Mapper
//自动扫描包 @MapperScan("com.xie.mybatis.mapper")
@SpringBootApplication
//或者
//表示这是一个mybatis的mapper类
@Mapper
public interface UserMapper {
}
//被spring管理 也可以@Component
@Repository
@Mapper
public interface UserMapper {
}
可以将映射文件写在resources下面,通过properties/yml文件配置 进去

映射文件 sql语句
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xie.mybatis.mapper.UserMapper">
<select id="queryUserList" resultType="User" useCache="true">
select *
from user
</select>
<select id="queryUserById" resultType="User">
select *
from user
where id = #{id}
</select>
<insert id="addUser" parameterType="User">
insert into user (id, name, pwd)
values (#{id}, #{name}, #{pwd})
</insert>
<update id="updateUser" parameterType="User">
update user
set id=#{id},
name=#{name},
pwd=#{pwd}
</update>
<delete id="deleteUser" parameterType="int">
delete
from user wehere id=#{id}
</delete>
</mapper>
省略业务层简单实现
RestController
public class UserController {
@Autowired
private UserMapper mapper;
@GetMapping("/queryAll")
public List<User> queryAll(){
List<User> userList = mapper.queryUserList();
for (User user : userList) {
System.out.println(user);
}
return userList;
}
//restful风格
@GetMapping("/queryId/{id}")
public User queryId(@PathVariable int id){
User user1 = mapper.queryUserById(id);
System.out.println(user1);
return user1;
}
//@RequestBody 限定了前端传递的参数必须为json格式,
//用POST方式进行提交,而且@RequestBody 只能有一个。
//@RequestParam()可以有多个,用于接收url中的key-value参数的传递。
// 通常我们用于get方式的请求
@GetMapping("/queryId2")
public User queryId2(@RequestParam("userId") int id){
User user1 = mapper.queryUserById(id);
System.out.println(user1);
return user1;
}
}
SpringSecurity 主要目标是认证Authentication 授权 Authorization
导入web和thymleaf依赖 引入spring-boot-starter-security
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--导入thymleaf依赖 我们都是基于3.x开发--> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-java8time</artifactId> </dependency>
注意:
-
WebSecurityConfigurerAdapter 自定义Security策略 适配器模式
-
AuthenticationManagerBuilder 自定义认证策略 建造者模式
-
@EnableWebSecurity 开启WebSecurity模式 @Enable***开启某功能
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//链式编程 授权
@Override
protected void configure(HttpSecurity http) throws Exception {
//首页所有人可以访问 功能页只有对应有权限的人才能访问 添加认证请求 ,所有的都能
//请求授权的规则
http.authorizeRequests().antMatchers("/").permitAll()
//vip1 角色能访问
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level4/**").hasRole("vip3");
//没有权限会默认到登录页面,需要开启登录的页面
http.formLogin();
}
//认证,springboot 2.1.x可以直接使用
//密码编码 PasswordEncoder
//新增了很多的加密方法
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//这里从内存 正常聪哥数据库读
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("jack").password(new BCryptPasswordEncoder().encode("123456"))
.roles("vip1","vip2").and()
.withUser("root").password(new BCryptPasswordEncoder().encode("root")).roles("vip3").and()
.withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
}
}
通过数据库内容认证











