Java教程

SpringBoot笔记整理

本文主要是介绍SpringBoot笔记整理,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

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: _

基础语法

1Fragment inclusionth:insert``th:replace
2Fragment iterationth:each
3Conditional evaluationth:if``th:unless``th:switch``th:case
4Local variable definitionth:object``th:with
5General attribute modificationth:attr``th:attrprepend``th:attrappend
6Specific attribute modificationth:value``th:href``th:src``...
7Text (tag body modification)th:text``th:utext
8Fragment specificationth:fragment
9Fragment removalth: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");
​
    }
​
}

通过数据库内容认证

 

这篇关于SpringBoot笔记整理的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!