文章目录
前言
提示:以下是本篇文章正文内容,下面案例可供参考
一、什么是springboot
1.1、回顾什么是spring
spring是为了解决企业级应用开发的复杂性而创建的,简化开发
spring是如何简化Java开发的
1、基于POJO的轻量级和最小侵入性编程
2、通过IOC,依赖注入(DI)和面向接口实现松耦合
3、基于切面(AOP)和惯例进行声明式编程
4、通过切面和模版减少样式代码
1.2、什么是springboot
1.3、springboot的优点
- 为所有Spring开发者更快的入门
- 开箱即用,提供各种默认配置来简化项目配置。
- 内嵌式容器简化Web项目
- 没有冗余代码生成和XML配置的要求
二、微服务架构
2.1、什么是微服务
微服务是一种架构风格,它要求我们在开发一个应用的时候,这个应用必须构建成一系列小服务的组合;可以通过http的方式进行互通。要说微服务架构,先得说说过去我们的单体应用架构。
2.2、单体应用架构
所谓单体应用架构(all in one)是指,我们将一个应用的中的所有应用服务都封装在一个应用中。无论是ERP、CRM或是其他什么系统,你都把数据库访问,web访问,等等各个功能放到一个war包内。
优点:
- 易于开发和测试;
- 十分方便部署;
- 当需要扩展时,只需要将war复制多份,然后放到多个服务器上,再做个负载均衡就可以了。
缺点:
- 哪怕我要修改一个非常小的地方,我都需要停掉整个服务,重新打包、部署这个应用war包。特别是对于一个大型应用,我们不可能吧所有内容都放在一个应用里面,我们如何维护、如何分丁合作都是问题。
三、第一个SpringBoot程序
配置:
- jdk1.8
- maven3.6.1
- springboot最新版
- IDEA
该端口号:server.port=8081
3.1、原理初深
pom.xml
- spring-boot-dependencie:核心依赖在父工程中
- 我们在写或者引入一些SPringboot依赖的时候,不需要指定版本,就因为有这些版本仓库
启动器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
- 启动器:说白了就是Springboot的启动场景
- 比如spring-boot-starter-web,他就会帮我们自动导入web环境所有的依赖!
- springboot会将所有的功能场景,都变成一个个的启动器
- 我们要使用什么功能,就只需要找到对应的启动器就可以了 ‘ starter ’
主程序
/@SpringBootApplication:标注这个类是一个springbot的应用
@SpringBootApplication
public class HelloworldApplication {
public static void main(String[] args) {
//将springboot应用启动,应用反射,该方法返回一个configurableApplicationContext对象
//参数一、应用入口的类 参数类:命令行参数
SpringApplication.run(HelloworldApplication.class, args);
}
}
- 注解
@SpringBootConfiguration:springboot的配置
@Configuration:spring配置类
@Component:说明这是一个spring的组件
@EnableAutoConfiguration
@AutoConfigurationPackage:自动配置包
@Import({AutoConfigurationPackages.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;
}
结论:springboot所有的配置都是在启动的时候扫描并加载:spring.factories所有的自动配置类都在这里,但是不一定生效,要判断条件是否成立,只要导入了对应的start,就有对应的启动器了,有了启动器,我们自动配置就会生效,然后配置就成功
1、springboot在启动的时候,从类路径下/META-INF/spring.factories获取指定的值
2、将这些自动配置的类导入容器,自动配置类就会生效,帮我们进行自动配置
3、以前我们需要自动配置的东西,现在springboot帮我们做了
4、整合javaEE,解决方案和自动配置的东西都在spring-boot-autoconfigure-2.2.0RELEASE.jar这个包下
5、它会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器;
6、容器中也会存在非常多的xxxAutoConfiguration的文件(@bean),就是这些类给容器中导入了这个场景需要的所有组件,并自动配置。@Configuration,javaConfig
7、有了自动配置类,免去了我们手动编写配置的工作
SpringApplication.run分析【分析该方法主要分两部分:一是SpringApplication的实例化,二是run方法的执行】
- SpringApplication
这个类主要做了四件事情
1、推断应用的类型是普通的项目还是Web项目
2、查找并加载所有可用初始化器,设置到initializers属性中
3、找出所有的应用程序监听器,设置到listeners属性中
4、推断并设置main方法的定义类,找到运行的主类
四、yaml语法讲解
4.1、配置文件
springboot使用一个全局的配置文件,配置文件名称是固定的
-
application.properties
- 语法结构:key=value
-
application.yml
- 语法结构:key:空格 value
配置文件的作用:修改springboot自动配置的默认值,因为springboot在底层都给我们自动配置好了
4.2、YAML
yaml配置:
server:
port: 80800
xml配置
<server>
<port>8081</port>
</server>
4.3、给属性赋值的几种方式
遇到的问题
这里导入配置文件处理器就行了
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> </dependency>
程序实现
1、将默认的application.properties后缀修改为yml
2、编写实体类
//person类
@Component//组成bean
@ConfigurationProperties(prefix = "person")
/*
ConfigurationProperties作用:
将配置文件中的每一个属性的值,映射到这个组件中,告诉springboot将本类中的所有属性和配置文件中相关的配置进行绑定
参数prefix=“person”:将配置文件中的person下面的所有属性一一对应
只有这个组件是容器中的组件,才能使用容器提供的ConfigurationProperties功能
*/
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;
//省略get/set方法和构造器方法
}
//动物类
public class Dog {
private String name;
private Integer age;
//省略get/set方法和构造器方法
3、导入配置文件处理器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
4、编写yml配置文件
基础语法:
k:(空格)v
以此来表示一对键值对;以空格的缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的
person:
name: 小徐
age: 18
happy: false
birth: 2022/03/29
maps: {k1: v1,k2: v2}
lists:
- code
- music
- girl
dog:
name: 旺财
age: 3
5、调试
@SpringBootTest
class Springboot02ConfigApplicationTests {
@Autowired
private Person person;
@Test
void contextLoads() {
System.out.println(person);
}
}
比较
结论:
- 配置yml和配置properties都可以获取到值,强烈推荐yml
- 如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用一下@value
- 如果说,我们专门编写了一个JavaBean来和配置文件进行映射,就直接使用
@configurationProperties,不要犹豫!
4.4、配置文件加载位置
springboot启动会扫描以下位置的application.properties或者application.yml文件作为Springboot的默认配置文件
4.5、多环境配置
五、Springboot Web开发
自动装配
- xxxAutoConfiguraion…:向容器中自动配置组件
- xxxProperties…:自动配置类,装配配置文件中自定义的一些内容
5.1、静态资源【03】
总结:
1、在springboot中我们可以使用以下方式处理静态资源
- webjars ——loca1host:8080/webjars/
- public,static,/**,resources —— localhost :8080/
2、优先级:resources>static(默认)>public
5.2、模板引擎
第一步:导入thymeleaf
<!--Thymeleaf-->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
第二步:将html页面放在templates里
<body>
<!--所有的html元素都可以被thymeleaf替换接管: th:元素名-->
<div th:text="${msg}"></div>
<hr/>
<h3 th:each="user:${user}" th:text="${user}"></h3>
</body>
第三步,测试
//@RestController:返回一个字符串
//在templates目录下的所有页面,只能通过controller来跳转
@Controller
public class HelloController {
@GetMapping("/test1")
public String hello(Model model){
model.addAttribute("msg","hello templates");
//遍历
model.addAttribute("user", Arrays.asList("小徐","小双"));
return "test";
}
}
【thymeleaf语法】
https://www.jianshu.com/p/d1370aeb0881
员工管理系统:
1、首页配置:所有页面的静态资源配置都需要使用thymeleaf接管
2、页面国际化:
- 1、我们需要配置i18n文件
- 2、我们如果需要在项目中进行按钮自动切换,我们需要自定义一个国际化主键【LocaleResolver】
- 记得将自己写的组件配置到spring容器中【@Bean】
六、Springboot整合数据库
6.1、整合JDBC
1、依赖:jdbc API、Mysql Driver
2、 配置数据库文件【application.yml】
spring:
datasource:
username: root
password: xuxiaoqiang1234
url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
3、测试数据库连接【springboot04DateApplicationTests】
@SpringBootTest
class Springboot04DataApplicationTests {
@Autowired
DataSource dataSource;
@Test
void contextLoads() throws SQLException {
//查看以下默认的数据源:class com.zaxxer.hikari.HikariDataSource
System.out.println(dataSource.getClass());
System.out.println("nihao ");
//获得数据库连接
Connection connection=dataSource.getConnection();
System.out.println(connection);
//xxxx Template:springboot已经配置好模板bean,拿来即用CRUD
//关闭
connection.close();
}
}
4、数据库的增删改查【JdbcController】
@RestController
public class JdbcController {
@Autowired
JdbcTemplate jdbcTemplate;
//查询数据库的所有信息
//没有实体类,数据库的东西怎么获取?用map
@GetMapping("/user")
public List<Map<String,Object>> query(){
String sql="select * from user ";
List<Map<String, Object>> list_maps = jdbcTemplate.queryForList(sql);
return list_maps;
}
//添加数据
@GetMapping("/addUser")
public String addUser(){
String sql="insert into mybatis.user(id,name,pwd) values(5,'双','32123')";
System.out.println(sql);
jdbcTemplate.update(sql);
return "addUser-ok";
}
//修改数据
@GetMapping("/upDateUser/{id}")
public String upDateUser(@PathVariable("id") int id){
String sql="update mybatis.user set name=?,pwd=? where id="+id;
//封装
Object[] objects = new Object[2];
objects[0]="邱";
objects[1]="43234";
jdbcTemplate.update(sql,objects);
return "upDateUser-ok";
}
//删除数据
@GetMapping("/deleteUser/{id}")
public String deleteUser(@PathVariable("id") int id){
String sql="delete from mybatis.user where id=?";
jdbcTemplate.update(sql,id);
return "deleteUser-ok";
}
}
6.2、整合Druid数据源
1、引入数据源
<!--Druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.5</version>
</dependency>
2、指定使用druid的数据源【application.yml】
type: com.alibaba.druid.pool.DruidDataSource
3、测试
@SpringBootTest
class Springboot04DataApplicationTests {
@Autowired
DataSource dataSource;
@Test
void contextLoads() throws SQLException {
//查看以下默认的数据源:class com.zaxxer.hikari.HikariDataSource
System.out.println(dataSource.getClass());
System.out.println("nihao ");
//获得数据库连接
Connection connection=dataSource.getConnection();
System.out.println(connection);
//xxxx Template:springboot已经配置好模板bean,拿来即用CRUD
//关闭
connection.close();
}
}
七、 整合Mybatis框架
1、导入依赖
<!--mybatis-spring-boot-starter:整合-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
2、配置数据库信息
【application.properties】
spring.datasource.username=root
spring.datasource.password=xuxiaoqiang1234
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
3、测试
@SpringBootTest
class Springboot05MybatisApplicationTests {
@Autowired
DataSource dataSource;
@Test
void contextLoads() throws SQLException {
System.out.println(dataSource.getClass());
System.out.println(dataSource.getConnection());
}
}
4、写UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.mapper.UserMapper">
<!-- 查询所有用户-->
<select id="queryUserList" resultType="User">
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 name=#{name},pwd=#{pwd} where id = #{id}
</update>
<!--删除一个用户-->
<delete id="deleteUser" parameterType="int">
delete from user where id =#{id}
</delete>
</mapper>
5、整合mybatis【application.properties】
#整合mybatis
mybatis.type-aliases-package=com.kuang.pojo
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
6、编写接口【UserMapper】
@Mapper//表示这是一个mybatis的mapper类
@Repository
public interface UserMapper {
//查询所有用户
List<User> queryUserList();
//查询一个用户
User queryUserById(int id);
//增加一个用户
int addUser(User user);
//修改一个用户
int updateUser(User user);
//删除一个用户
int deleteUser(int id);
}
7、执行增删改查
@RestController
public class UserController {
@Autowired
private UserMapper userMapper;
//查询所有用户
@GetMapping("/queryUserList")
public List<User> queryUserList(){
List<User> userList = userMapper.queryUserList();
for (User user : userList) {
System.out.println(user);
}
return userList;
}
//增加一个用户
@GetMapping("addUser")
public String addUser(){
User user=new User();
user.setId(5);
user.setName("娇");
user.setPwd("78326");
userMapper.addUser(user);
return "Ok";
}
@GetMapping("updateUser")
//修改一个用户
public String updateUser(){
User user=new User();
user.setId(1);
user.setName("李丽");
user.setPwd("64326");
userMapper.updateUser(user);
return "Ok";
}
//删除一个用户
@GetMapping("deleteUser")
public String deleteUser(){
userMapper.deleteUser(3);
return "Ok";
}
}
八、SpringSecurity(安全)
8.1、初识
SpringSecurity 是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型,他可以实现强大的Web安全控制,对于安全控制,我们仅需要引入spring-boot-starter-security模块,进行少量的配置,即可实现强大的安全管理!
记住几个类
- websecurityConfigurerAdapter:自定义Security策略
- AuthenticationManagerBuilder:自定义认证策略
- @EnableWebSecurity:开启WebSecurity模式
Spring Security的两个主要目标是“认证"和“授权”(访问控制)
8.2、案例
@EnableWebSecurity
public class SecunrityConfig extends WebSecurityConfigurerAdapter {
//授权
@Override
protected void configure(HttpSecurity http) throws Exception {
//首页所有人可以访问,但是功能页有权限的人才能访问
//请求获取权限的规则
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
//没有权限默认跳到登录页面
http.formLogin();
//开启注销功能
http.logout();
}
//认证,springboot 2.1.x可以直接使用
//在spring Secutity 5.0+新增了很多加密的方法:passwordEncoder(new BCryptPasswordEncoder())
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
//这些数据正常应该从数据库中读取
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("小徐").password(new BCryptPasswordEncoder().encode("12345")).roles("vip2","vip3")
.and()
.withUser("双").password(new BCryptPasswordEncoder().encode("1234")).roles("vip1")
.and()
.withUser("root").password(new BCryptPasswordEncoder().encode("123")).roles("vip2","vip2","vip3");
}
}
错误: There is no PasswordEncoder mapped for the id “null”
- 在spring Secutity 5.0+新增了很多加密的方法:passwordEncoder(new BCryptPasswordEncoder())
九、Swagger
9.1、springboot集成swagger
1、新建一个springboot=web项目【springboot-07-swagger】
2、导入相关依赖
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
3、编写一个Hello工程
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
return "hello";
}
}
4、配置swagger==》config
@Configuration
@EnableSwagger2//开启swagger2
public class SwaggerConfig {
}
5、测试运行【http://localhost:8080/swagger-ui.html】
9.2、配置swagger
1、Swagger的bean实例Docket
@Configuration
@EnableSwagger2//开启swagger2
public class SwaggerConfig {
//配置了swagger的Docket的bean实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
}
2、配置Swagger信息=apiInfo
//配置Swagger信息=apiInfo
private ApiInfo apiInfo() {
//作者信息
Contact contact=new Contact("小徐","https://www.bilibili.com/","2318654821@qq.com");
return new ApiInfo(
"小徐的天地",
"彼方自有荣光在",
"1.0",
"urn:tos",
contact,
"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList());
}
}
9.3、Swagger配置扫描接口
Docket.select()
@Configuration
@EnableSwagger2//开启swagger2
public class SwaggerConfig {
//配置了swagger的Docket的bean实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//RequestHandlerSelectors:配置要扫描接口的方式
//basePackage:指定要扫描的包
//any:扫描全部
//none:不扫描
//withClassAnnotation:扫描类上的注解,参数是一个注解的反射对象
//withMethodAnnotation:扫描方法上的注解
.apis(RequestHandlerSelectors.basePackage("com.kuang.controller"))
//paths():过滤什么路径
.paths(PathSelectors.ant("/kuang/**"))
.build();
}