初识springboot

Springboot

##创建springboot项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yacC7LMx-1683693522240)(C:\Users\MU\AppData\Roaming\Typora\typora-user-images\image-20221218235805516.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FZXU7LGA-1683693522241)(C:\Users\MU\AppData\Roaming\Typora\typora-user-images\image-20221218235859885.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wdRKQu82-1683693522242)(C:\Users\MU\AppData\Roaming\Typora\typora-user-images\image-20221218235919794.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jXZF2C9p-1683693522242)(C:\Users\MU\AppData\Roaming\Typora\typora-user-images\image-20221218235938357.png)]

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这个包下。
  5. 它会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器。(如同spring中注入bean)
  6. 容器中也会存在非常多的xxxAutoConfiguration的文件(@Bean),就是这些类给容器中导入了这个场景需要的所有组件,并自动配置,@Configuration,JavaConfig。
  7. 有了自动配置类,免去了我们手动编写配置文件的工作。

自动装配原理的精髓

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

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

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

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

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

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

##SpringBoot Web开发

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

静态资源

获取静态资源源码(在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});
                    }

                });
            }
        }

在WebMvcAutoConfiguration.class中的getStaticLocations()方法:在static resource public目录下读取静态资源

 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;

总结

在springboot中,我们可以使用以下处理静态资源,文件建在resources目录下

  • webjars localhost:8080/wabjars/目录结构(可以读取静态资源)
  • localhost:8080/资源名 也可以获取到static resource public目录下的静态资源
  • public, static, /**, resources localhost:8080/访问页面
  • resources>static>public

首页定制

源码:在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,放在资源目录(resource下的resource,public,static)下可以被访问到

  • 首页配置:注意点,所有页面的静态资源都需要使用thymeleaf接管;@{}
  • 页面国际化:
    1. 我们需要配置i18n文件(国际化简写)
    2. 我们如果需要在项目中进行按钮自动切换,我们需要自定义一个组件 LocaleResolver
    3. 记得将自己写的组件配置到springrongqi中 @Bean
    4. #{}

###thymeleaf模板引擎

导入thymeleaf依赖

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


在html中导入thymeleaf命名空间

xmlns:th="http://www.thymeleaf.org"

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;

在templates资源文件下的文件,只能通过controller进行页面跳转

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

<!--/*@thymesVar id="msg" type="java.lang.String"*/-->
<div th:text="${msg}"></div>

springmvc配置

springboot的默认配置其实就是以前springmvc的手动配置,你可以通过重新编写配置来更改默认配置,多读源码学习!!!

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

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

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

##Data

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

spring:
  datasource:
    username: root
    password: '123456'
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=false
    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;
    }
}

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

##整合Mybatis框架

添加依赖

<!-- 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>
123456

在application.properties中添加mybatis

#整合mybatis
mybatis.type-aliases-package=com.mu.pojo
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

在资源文件中新建mybatis.mapper,将xxxMapper.xml文件放在下面

  • 编写sql

、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>
    1234
    
  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简介

Swagger

  • 号称世界上最流行的Api框架;
  • RestFul Api文档在线生成工具=>Api文档与API定义同步更新
  • 直接运行,可以在线测试API接口;
  • 支持多种语言:(Java,Php…)

SpringBoot集成Swagger

  1. 新建一个SpringBoot项目=>web项目

  2. 导入依赖

            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>2.9.2</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>2.9.2</version>
            </dependency>
    

​ 3.编写一个Hello工程

​ 4.配置Swagger===>Config

@Configuration
@EnableSwagger2  //开启Swagger2
public class SwaggerConfig {
 
}

​ 5.配置swagger信息

package com.mu.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;

@Configuration
@EnableSwagger2 //开启swagger2
public class SwaggerConfig {

    //配置了Swagger的Docket的bean实例
    @Bean
    public Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
    }

    //配置swagger信息=>apiInfo
    private ApiInfo apiInfo() {
        Contact contact = new Contact("慕余", "https://blog.csdn.net/qq_51326491?type=blog", "309***97@qq.com");
        return new ApiInfo(
                "SwaggerAPI文档",
                "别回头看",
                "v1.0", "urn:tos",
                contact,
                "Apache 2.0",
                "http://www.apache.org/licenses/LICENSE-2.0",
                new ArrayList()
        );
    }
}

启动报错:Failed to start bean ‘documentationPluginsBootstrapper’; nested exception is java.lang.NullPointerException

解决方案:
在配置文件application.properties中加入以下配置

spring.mvc.pathmatch.matching-strategy=ANT_PATH_MATCHER

如果是application.yml就加入

spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher

Swagger配置扫描接口

    //配置了Swagger的Docket的bean实例
    @Bean
    public Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2)
            	.apiInfo(apiInfo())
            	//.enable(false)  enable是否启动swagger,如果为flase,则swagger不能在浏览器中访问
                .select()
                //RequestHandlerSelectors,配置要扫描接口的方式
                //basePackage:指定要扫描的包
                //any():扫描全部
                //none():不扫描
                //withClassAnnotation:扫描类上的注解,参数是一个注解的反射现象
                //withMethodAnnotation:扫描方法上的注解
                .apis(RequestHandlerSelectors.basePackage("com.mu.controller"))
                //path(),过滤路径
                // .paths(PathSelectors.ant("/mu/**"))
                .build();
    }

选择开发环境中使用swagger

  @Bean
    public Docket docket(Environment environment) {

        //设置要显示的Swagger环境
        Profiles profiles = Profiles.of("dev", "test");
        //通过environment.acceptsProfiles判断是否处在自己设定的环境当中
        boolean flag = environment.acceptsProfiles(profiles);

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .enable(flag)  //enable是否启动swagger,如果为flase,则swagger不能在浏览器中访问
                .select()
                .build();
    }

配置API文档分组

return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .groupName("yiyi") //分组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BYIo54Eg-1683693522243)(C:\Users\MU\Desktop\笔记\springswaggerapi分组.jpg)]

配置多个分组

 @Bean
    public Docket docket1(){
        return new Docket(DocumentationType.SWAGGER_2).groupName("A");
    }

    @Bean
    public Docket docket2(){
        return new Docket(DocumentationType.SWAGGER_2).groupName("A");
    }

    @Bean
    public Docket docket3(){
        return new Docket(DocumentationType.SWAGGER_2).groupName("A");
    }
    
    @Bean
    public Docket docket(Environment environment) {

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7chxvstW-1683693522244)(C:\Users\MU\Desktop\笔记\swagger分组.jpg)]

swagger配置扫描接口

接口的使用:

实体类:

//@Api(注释)
@ApiModel("用户实体类")
public class User {
    @ApiModelProperty("用户名")
    public String username;
    @ApiModelProperty("密码")
    public String password;
}

扫描接口

//只要我们的接口中,返回值中存在实体类,他就会被扫描到Swagger中
@PostMapping("/user")
public User user(){
    return new User();
}

网站显示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kV5np7YF-1683693522245)(C:\Users\MU\Desktop\笔记\swagger接口实现实体类.jpg)]

controller中方法接口扫描

@GetMapping("/hello")
public String hello(){
    return "hello";
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WAlGKiLJ-1683693522245)(C:\Users\MU\Desktop\笔记\swagger方法接口实现.jpg)]

还可以在方法中传入参数在线测试

@GetMapping("/hello")
public User hello(@Apiparam("用户") User user){//@Apiparam 是对参数的注释说明,只是为了加入中文说明
    return user;
}

总结:

优势:

  1. 我们可以对一些接口属性添加注释信息
  2. 接口文档实时更新
  3. 在线测试

任务

异步任务

异步任务是那些被引擎放在一边,不进入主线程、而进入任务队列的任务。只有引擎认为某个异步任务可以执行了(比如 Ajax 操作从服务器得到了结果),该任务(采用回调函数的形式)才会进入主线程执行。排在异步任务后面的代码,不用等待异步任务结束会马上运行,也就是说,异步任务不具有“堵塞”效应。

(先执行主线程,然后主线程中的异步方法进入任务队列,主线程继续执行,无序等待异步任务完成)

在启动类上添加注释

@EnableAsyns//开启异步注解功能

在service方法上添加注释

@Async   //告诉spring这是一个异步方法

邮件任务

1.导入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

2.得去qq邮箱 账号设置开启SMTP服务

3.配置

spring.profiles.active=dev
spring.mail.username=1795308632@qq.com
spring.mail.password=
spring.mail.host=smtp.qq.com
#开启加密验证(qq邮箱需要)
spring.mail.properties.mail.smtp.sll.enble=true

4.发送邮件

@Autowired
JavaMailSenderImpl mailSender;
@Test
void contextLoads() {
    SimpleMailMessage mailMessage=new SimpleMailMessage();
    mailMessage.setSubject("yiyi,你好");  //主题
    mailMessage.setText("谢谢");//内容
    mailMessage.setTo("1795308632@qq.com");//发送到
    mailMessage.setFrom("1795308632@qq.com");//来自

    mailSender.send(mailMessage);
}


        //复杂的邮件
        MimeMessage mimeMessage=mailSender.createMimeMessage();
        MimeMessageHelper helper=new MimeMessageHelper(mimeMessage,true);
        helper.setSubject("yiyi,你好");
        helper.setText("");

定时任务

在启动类上添加注释

@EnableScheduling//开启定时功能的注解

在service方法上添加注释

@Scheduling(cron="0 * * * * 0-7")//什么时候执行,里面填入cron表达式// 秒 分 时 日 月 星期几    *d
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值