IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Springboot学习记录 -> 正文阅读

[Java知识库]Springboot学习记录

Springboot学习记录

一、原理初探

springboot所有自动配置都是在启动的时候扫描并加载:spring.factories所有的自动配置类都在这里面,但不一定生效,要判断条件是否成立,只要导入了对应的start,就有对应的启动器了,有了启动器,我们自动装配就会生效,然后配置成功!

  • @SpringBootApplication:springboot应用注解,核心注解
  • @Configuration:自动装配
  • @ConditionOnxxxx:条件满足才会触发成功
  • @AutoConfigurexxxx:自动装配xx
  • @Enablexxxx:开启某个功能
  1. springboot在启动的时候,从类路径下/META-INF/spring.factories获取指定的值。

  2. 将这些自动配置的类导入容器,自动配置就会生效,帮我们进行自动配置。

  3. 以前我们需要自动配置的东西,现在springboot帮我们做了。

  4. 整个javaEE,解决方案和自动配置的东西都在spring-boot-autoconfigure-2.7.3.jar这个包下。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fO28tAky-1666933329202)(img/image-20221024105706114.png)]

  5. 它会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器。

  6. 容器中也会存在非常多的xxxAutoConfiguration的文件(@Bean),就是这些类给容器中导入了这个场景需要的所有组件,并自动配置,@Configuration,JavaConfig。

  7. 有了自动配置类,免去了我们手动编写配置文件的工作。

自动装配原理的精髓

  1. springboot启动会加载大量的自动配置类

  2. 我们看我们需要的功能有没有在springboot默认写好的自动配置类当中

  3. 我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在其中,我们就不需要在手动配置了)

  4. 给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可

    xxxxAutoConfiguration:自动配置类;给容器中添加组件

    xxxxProperties:封装配置文件中相关属性

二、yaml

三、jsr303校验

@Validated :数据校验

四、常用方法

  1. 在application.yml中添加debug: true

    来查看哪些自动配置类生效,哪些没有生效!

    debug: true
    
  2. @Configuration :扩展springmvc

  3. EnableWebMvc: 导入了一个类:DelegatingWebMvcConfiguration:从容其中获取所有的webmvcconfig

五、SpringBoot Web开发

要解决的问题:

  • 导入静态资源
  • 首页
  • jsp,模板引擎Thymeleaf
  • 装配扩展SpringMVC
  • 增删改查
  • 拦截器
  • 国际化
5.1、静态资源

源码:在WebMvcAutoConfiguration.class下的方法中:

public void addResourceHandlers(ResourceHandlerRegistry registry) {
            if (!this.resourceProperties.isAddMappings()) {
                logger.debug("Default resource handling disabled");
            } else {
                this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
                this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
                    registration.addResourceLocations(this.resourceProperties.getStaticLocations());
                    if (this.servletContext != null) {
                        ServletContextResource resource = new ServletContextResource(this.servletContext, "/");
                        registration.addResourceLocations(new Resource[]{resource});
                    }

                });
            }
        }

同时在上面的getStaticLocations()方法中:

 public static class Resources {
        private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};
        private String[] staticLocations;
        private boolean addMappings;
        private boolean customized;
        private final WebProperties.Resources.Chain chain;
        private final WebProperties.Resources.Cache cache;

总结

  1. 在springboot中,我们可以使用以下处理静态资源,文件建在resources目录下
    • webjars localhost:8080/wabjars/目录结构
    • public, static, /**, resources localhost:8080/访问页面
    • resources>static>public
5.2、首页

源码:在WebMvcAutoConfiguration.class下的方法中:

private Resource getWelcomePage() {
            String[] var1 = this.resourceProperties.getStaticLocations();
            int var2 = var1.length;

            for(int var3 = 0; var3 < var2; ++var3) {
                String location = var1[var3];
                Resource indexHtml = this.getIndexHtml(location);
                if (indexHtml != null) {
                    return indexHtml;
                }
            }

            ServletContext servletContext = this.getServletContext();
            if (servletContext != null) {
                return this.getIndexHtml((Resource)(new ServletContextResource(servletContext, "/")));
            } else {
                return null;
            }
        }

        private Resource getIndexHtml(String location) {
            return this.getIndexHtml(this.resourceLoader.getResource(location));
        }

        private Resource getIndexHtml(Resource location) {
            try {
                Resource resource = location.createRelative("index.html");
                if (resource.exists() && resource.getURL() != null) {
                    return resource;
                }
            } catch (Exception var3) {
            }

            return null;
        }

从中我们可以得出我们的首页,名字命名为index.html,放在资源目录下即可,都可以被访问到

  • 首页配置:注意点,所有页面的静态资源都需要使用thymeleaf接管;@{}

  • 页面国际化:

    1. 我们需要配置i18n文件
    2. 我们如果需要在项目中进行按钮自动切换,我们需要自定义一个组件LocaleResolver
    3. 记得将自己写的组件配置到springrongqi中@Bean
    4. #{}

    页面国际化(页面语言转换)地区解析器源码:

    /**1.WebMvcAutoConfiguration.class中*/
    public LocaleResolver localeResolver() {
        if (this.webProperties.getLocaleResolver() == org.springframework.boot.autoconfigure.web.WebProperties.LocaleResolver.FIXED) {
            return new FixedLocaleResolver(this.webProperties.getLocale());
        } else {
            AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
            localeResolver.setDefaultLocale(this.webProperties.getLocale());
            return localeResolver;
        }
    }
    /**从这里我们可以看见有个地区解析器,用户没设置的话就是走默认的,如果设置的话,就是走用户设定的,这里有一个new的方法,我们可以点进去看AcceptHeaderLocaleResolver源码*/
    
        
    /**2.AcceptHeaderLocaleResolver中*/
    public class AcceptHeaderLocaleResolver implements LocaleResolver {
        private final List<Locale> supportedLocales = new ArrayList(4);
        @Nullable
        private Locale defaultLocale; 
    /**可以发现,这里是实现一个LocaleResolver接口,所以我们也要实现这个接口,如下我们自己写的组件*/
        
        
    /**3.这个接口需要有两个重写方法根,据返回值来看,主要重写第一个方法,找到AcceptHeaderLocaleResolver下面的方法resolveLocale*/
    public Locale resolveLocale(HttpServletRequest request) {
            Locale defaultLocale = this.getDefaultLocale();
            if (defaultLocale != null && request.getHeader("Accept-Language") == null) {
                return defaultLocale;
            } else {
                Locale requestLocale = request.getLocale();
                List<Locale> supportedLocales = this.getSupportedLocales();
                if (!supportedLocales.isEmpty() && !supportedLocales.contains(requestLocale)) {
                    Locale supportedLocale = this.findSupportedLocale(request, supportedLocales);
                    if (supportedLocale != null) {
                        return supportedLocale;
                    } else {
                        return defaultLocale != null ? defaultLocale : requestLocale;
                    }
                } else {
                    return requestLocale;
                }
            }
        }
    
    /**4.点击Locale可看见其结构*/
    /** Useful constant for language.*/
    static public final Locale SIMPLIFIED_CHINESE = createConstant("zh", "CN");
       
    

    故我们可以根据上面的源码进行添加我们的组件:

    public class MyLocaleResolver implements LocaleResolver {
    
        //解析请求
        @Override
        public Locale resolveLocale(HttpServletRequest request) {
            //获取请求中的语言参数
            String language = request.getParameter("l");
    
            Locale locale = request.getLocale();    //如果没有就使用默认的;
            //如果请求的链接携带了国际化的参数
            if (!StringUtils.isEmpty(language)){
                //zh_CN
                String[] split = language.split("_");
                //国家,地区
                locale = new Locale(split[0], split[1]);
            }
            return locale;
        }
    
        @Override
        public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
    
        }
    }
    
    //自定义的国际化组件就生效了
    @Bean
    public LocaleResolver localeResolver(){
        return new MyLocaleResolver();
    }
    
    <a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
    <a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
    

    结果如图(实现中英文切换):

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z4RL8IMz-1666933329203)(img/image-20221025164215467.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-waELy4bc-1666933329203)(img/image-20221025164229839.png)]

5.3、thymeleaf模板引擎

导入thymeleaf依赖

<!--    Thymeleaf-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

源码:在ThymeleafProperties.class里面:

@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;
    private Integer templateResolverOrder;
    private String[] viewNames;
    private String[] excludedViewNames;
    private boolean enableSpringElCompiler;
    private boolean renderHiddenMarkersBeforeCheckboxes;
    private boolean enabled;
    private final ThymeleafProperties.Servlet servlet;
    private final ThymeleafProperties.Reactive reactive;

结论:

  • 我们将html文件放在templates资源文件下,然后controller就可以执行页面跳转了

在页面传递参数的时候,出现取值爆红的情况:

解决方案:在上面一行添加->

<!--@thymesVar id="msg" type="String"-->
5.4、springmvc配置

springboot有很多自动配置,原理都是一样的,通过这个WebMvc的自动配置原理分析,学会一种学习方式:

  • 通过源码探究,得出结论,这个结论一定是属于自己的,一通百通。

springboot的底层,大量的用到了这些设计细节思想,所以,没事需要多阅读源码!得出结论。

springboot在自动配置很多组件的时候,先看容器中有没有用户自己配制的,如果有,就使用用户的,反之,就是默认配置;如果有些组件可以存在多个,比如我们的视图解析器,就将用户和自己默认的组合起来。

  • 添加视图控制器
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index.html").setViewName("index");
    }

    //自定义的国际化组件就生效了
    @Bean
    public LocaleResolver localeResolver(){
        return new MyLocaleResolver();
    }
}

六、Data

配置application.yml,使用druid数据源,导入log4j

spring:
  datasource:
    username: root
    password: '123456'
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

    #Springboot 默认是不注入这些属性值得,需要自己绑定
    #druid 数据源专有配置
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRusMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true

    #配置监控统计的拦截器filter,stat:监控统计、log4j:日志记录、wall:防御sql注入
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

类似web.xml可以配置servlet和filter,举例

package com.heze.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.util.HashMap;

@Configuration
public class DruidConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource(){
        return new DruidDataSource();
    }
    @Bean
    //后台监控 :web.xml
    //因为SpringBoot 内置了servlet容器,所以没有web.xml,替代方法:ServletRegistrationBean
    public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
        //后台需要有人登录,账号密码配置
        HashMap<String, String> initParameters = new HashMap<>();
        //增加配置
        initParameters.put("loginUsername", "admin");
        initParameters.put("loginPassword", "123456");
        //允许谁可以访问
        initParameters.put("allow", "");

        bean.setInitParameters(initParameters);   //设置初始化参数
        return bean;
    }
    @Bean
    //filter
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean bean = new FilterRegistrationBean();

        bean.setFilter(new WebStatFilter());

        //可以过滤哪些请求
        HashMap<String, String> initParameters = new HashMap<>();
        //这些东西不进行统计
        initParameters.put("exclusions", "*.js,*.css,/druid/*");

        bean.setInitParameters(initParameters);
        return bean;
    }
}

结果:可以监听我们方法的使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RJOG1Lgu-1666933329204)(img/image-20221026173035678.png)]

七、整合Mybatis框架

7.1、添加依赖
<!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.2</version>
</dependency>
7.2、在application.properties中添加mybatis
#整合mybatis
mybatis.type-aliases-package=com.heze.pojo
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
7.3、在资源文件中新建mybatis.mapper,将xxxMapper.xml文件放在下面
  • 编写sql
7.4、xxxMapper.java使用@Mapper注解,表示这是一个mybatis的mapper类

八、SpringSecurity(安全)

在web开发中,安全第一位! 过滤器,拦截器~

功能性需求:否

做网站:在涉及隐私等时候需要考虑安全

所以

  • 安全需要在设计之初考虑

Spring Security is a framework that focuses on providing both authentication and authorization to Java applications.

翻译:Spring安全性是一个专注于为Java应用程序提供身份验证和授权的框架。

即:权限的释放:

  • 功能权限
  • 访问权限
  • 菜单权限
  • …拦截器,过滤器:大量的原生代码~冗余

从MVC-spring-springboot—框架思想 — > 逐步简化代码

记住几个类:

  • WebSecurityConfigurerAdpter:自定义Security策略 用来继承
  • AuthenticationManagerBuilder:自定义认证策略
  • @EnableWebSecurity:开启WebSecurity模式, @Enablexxxx开启某个功能

Spring Security的两个主要目标是“认证”和“授权”(访问控制)

“认证”(Authentication)

“授权”(Authorization)

步骤:

  1. 导入依赖

    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
    
  2. 在config下新建SecurityConfig.java

    授权

    @EnableWebSecurity
    public class SecurityConfig 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();
        }
        
        //没有权限就会跳到登录页面
            // /login
            // 定制登录页 loginPage("/toLogin")
            http.formLogin().loginPage("/toLogin").usernameParameter("user").passwordParameter("pwd").loginProcessingUrl("/login");
            
            //注销,开启了注销功能,跳到首页
            // 防止网站工具: get 、 post
            http.csrf().disable();  //关闭csrf功能,登录失败肯定存在原因
            http.logout().logoutSuccessUrl("/");
            
            //开启记住我功能 cookie,默认保存两周,自定义接收前端的参数
            http.rememberMe().rememberMeParameter("remember");
    }
    

    认证

    //认证
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                    .withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3")
                    .and()
                    .withUser("admin2").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
        }
    

九、Swagger简介

前后端分离

Vue + SpringBoot

后端时代:前端只用管理静态页面;html==>后端。模板引擎 JSP ==>后端是主力

前后端分离式时代

  • 后端:后端控制层,服务层,数据访问层
  • 前端:前端控制层,视图层
    1. 伪造后端数据,json。已经存在了,不需要后端,前端工程依旧能够跑起来
  • 前后端如何交互? ====>API
  • 前后端相对独立,松耦合
  • 前后端甚至可以部署在不同的服务器上

产生一个问题

  • 前后端集成联调,前端人员和后端人员无法做到“及时协商,尽早解决”,最终导致问题的集中爆发;

解决方案

  • 首先制定scheme【计划的提纲】,实时更新最新API,降低集成的风险;
  • 早些年:制定word计划文档;
  • 前后端分离:
    • 前端测试后端接口:postman
    • 后端提供接口,需要实时更新最新的消息及改动!
9.1、Swagger
  • 号称世界上最流行的Api框架;
  • RestFul Api文档在线生成工具=>Api文档与API定义同步更新
  • 直接运行,可以在线测试API接口;
  • 支持多种语言:(Java,Php…)
9.2、在项目中使用Swagger需要springbox
  • swagger2
  • ui
9.3、SpringBoot集成Swagger
  1. 新建一个SpringBoot项目=>web项目

  2. 导入依赖

    <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>3.0.0</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>3.0.0</version>
    </dependency>
    
    
  3. 编写一个Hello工程

  4. 配置Swagger===>Config

    @Configuration
    @EnableSwagger2  //开启Swagger2
    public class SwaggerConfig {
        
    }
    
  5. 测试运行

提一下:分布式Dubbo + ZooKeeper + SpringBoot

  • zookeeper:注册中心
  • dubbo-admin:是一个监控管理后台查看我们注册了哪些服务,哪些服务被消费了
  • Dubbo:jar包~

十、总结

? 简而言之:springboot省下了我们很多开发的代码量,使用起来比较简单,但是又由于整合了很多东西,我们在表面开发的时候需要提高读源码的能力,然后就是提高自己上手写项目的能力,理解逻辑,明白具体开发过程,然后查漏补缺,提升自己。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-11-05 00:12:25  更:2022-11-05 00:17:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年3日历 -2025/3/10 18:24:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码