SpringBoot学习

本文详细介绍了SpringBoot的核心特性,包括YML配置、注解集、Web开发、Thymeleaf使用、SpringSecurity和Shiro安全框架、Swagger接口文档以及分布式与异步处理。通过实例讲解了SpringBoot的配置优先级、Druid数据源、Mybatis整合、邮件发送和定时任务等关键知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SpringBoot

javase:OOP

mysql:持久化

html+css+js+jquery9框架:视图层View

javaweb:原始mvc网站

war:tomcat 运行

ssm:框架,简化开发,配置复杂

再简化,springmvc–>springboot 微服务架构

springboot :内嵌tomcat

  • ​ 配置:yml

  • ​ 自动装配–>简化开发

  • ​ 继承数据库druid

  • ​ 分布式开发:Dubbo+zookeeper

  • ​ swagger:接口文档

  • ​ SpringSecurity / shiro(拦截器功能,方便)

  • ​ Linux

  • ​ SpringCloud :真正涉及到微服务,Restful,Eureka,Ribbon,Feign,HyStrix

    • SpringCloud:config : git 上远程操作

    JVM:常见内容知道就好

原理:

spring-boot-starter-web : 帮忙导入各种web所需依赖

用什么功能,找到对应启动器

spring-boot-autoconfigure-2.2.0.RELEASE.jar ,整合javaEE

Spring-Boot-DevTools 热部署

Spring Boot的主要优点:

  • 为所有Spring开发者更快的入门
  • 开箱即用,提供各种默认配置来简化项目配置
  • 内嵌式容器简化Web项目
  • 没有冗余代码生成和XML配置的要求

YML

yml配置优先级顺序
  • ​ 项目下config文件下

    • 项目下
      • classpath(就是resource文件夹下)\config\文件下
        • classpath下
  • yml的@ConfigurationProperties

  • 松散绑定 yml 中last-name 与 lastName一样

  • JSR303 数据效验类似于一层过滤器验证,保证数据合法

  • 复杂类型封装,利用yml封装对象,使用@value就不支持了

注解集

  • @RestController = @Controller + @RespnseBody(用于返回Json数据,异步处理Ajax会用)

  • @RequsetMapping 通过返回跳转路径 + @RespnseBody返回值会写入到HTTP response body中,

Springboot Web开发

  • static资源
  • 首页
  • jsp,模板引擎Themeleaf
  • 装配扩展
  • crud
  • 拦截器
  • 国际化(中英文切换)
@PathVariable,@RequestParam,@RequestBody三者比较
注解 	支持的类型 	支持的请求类型 	支持的Content-Type 	请求示例

@PathVariable 	url 	GET 	所有 	/test/{id}
@RequestParam 	url 	GET 	所有 	/test?id=1
                Body 	POST/PUT/DELETE/PATCH 	form-data或x-www.form-urlencoded 	id:1
@RequestBody 	Body 	POST/PUT/DELETE/PATCH 	json 	{"id":1}

将接口改成以@RequestBody注解方式接受json请求数据,而后将接收到的json数据转化为json对象,可以使用json对象的get()方法取得参数值,代码如下:

@PostMapping("/account")
public Object insertAccount(@RequestBody JSONObject jsonParam) {
	String userName=jsonParam.get("userName").toString()
	...
静态资源如何导入?

spring.mvc.static.path

​ 资源访问的优先级来说,1.resources 2.static 3. public 可以直接访问 , 但若设置过static.path的话,直接就return了,不会看后面的了

源码如下

private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
      "classpath:/resources/", "classpath:/static/", "classpath:/public/" };

webjars:

  • ​ springboot可以以maven方式导入jquery

  • 在templates的页面一般只通过controller来访问

  • 改变首页路径需要用模板引擎thymeleaf

使用hashmap<>模拟数据完成Dao层功能
private static Map<Integer, Department> departments = null;

static{
    departments = new HashMap<Integer,Department>();

    departments.put(101,new Department(101,"销售部"));
    departments.put(102,new Department(102,"采购部"));
    departments.put(103,new Department(103,"运营部"));
    departments.put(104,new Department(104,"教育部"));
    departments.put(105,new Department(105,"工商部"));
}

以此为参考

Thymeleaf的使用

  • html标签加入

    <html lang="en" xmlns:th="http://www.thymeleaf.org">
        
    <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">
    <!-- Custom styles for this template -->
    <link th:href="@{/css/signin.css}" rel="stylesheet">
    
#关闭缓存
spring.thymeleaf.cache = false

关于前端模板的使用,

一般顶部导航栏topbar和侧边栏sidebar写在commons中

<!--导航栏-->
<div th:insert="~{common/commons::topbar(active='list.html')}"></div>
<!--侧边栏-->
				<div th:insert="~{common/commons::sidebar(active='list.html')}"></div>
Durid

监控数据的,springboot数据池用的HikariDataSource (号称java WEB最快的连接池)

!!!别忘了加log4j的依赖

对应一个个的Config

将springboot的datasource的type设置为Druid,数据库底层仍然是jdbc

  • filter 过滤 属性为字符串,stat为监控,log4j为日志,wall为防止sql注入

    Map<String,String>里加配置

    exclusions里*.js,*.css,/druid/*不进行统计

  • mock 测试

  • pool 测试

  • proxy 代理

  • sql ,Utils封装了一些东西可以toSting

  • support 支持,ibatis,hibernate,spring

配置:

  • 登陆的人,密码,可以访问权限人,不要忘记加上@Bean
  • springboot内置serlvet,想使用可以用替代方法
配置
/*
   将自定义的 Druid数据源添加到容器中,不再让 Spring Boot 自动创建
   绑定全局配置文件中的 druid 数据源属性到 com.alibaba.druid.pool.DruidDataSource从而让它们生效
   @ConfigurationProperties(prefix = "spring.datasource"):作用就是将 全局配置文件中
   前缀为 spring.datasource的属性值注入到 com.alibaba.druid.pool.DruidDataSource 的同名参数中
 */
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druidDataSource() {
    return new DruidDataSource();
}


//配置 Druid 监控管理后台的Servlet;
//内置 Servlet 容器时没有web.xml文件,所以使用 Spring Boot 的注册 Servlet 方式
//后台监控:相当于web.xml,ServletRegistrationBean
@Bean
public ServletRegistrationBean statViewServlet() {
    ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");

    // 这些参数可以在 com.alibaba.druid.support.http.StatViewServlet
    // 的父类 com.alibaba.druid.support.http.ResourceServlet 中找到
    //后台需要有人登陆,账号密码配置
    Map<String, String> initParams = new HashMap<>();
    initParams.put("loginUsername", "admin"); //后台管理界面的登录账号,key是固定的
    initParams.put("loginPassword", "123456"); //后台管理界面的登录密码

    //后台允许谁可以访问
    //initParams.put("allow", "localhost"):表示只有本机可以访问
    //initParams.put("allow", ""):为空或者为null时,表示允许所有访问
    initParams.put("allow", "");
    //deny:Druid 后台拒绝谁访问
    //initParams.put("deny", "192.168.1.20");表示禁止此ip访问

    //设置初始化参数
    bean.setInitParameters(initParams);
    return bean;
}



//配置 Druid 监控 之  web 监控的 filter
//WebStatFilter:用于配置Web和Druid数据源之间的管理关联监控统计
@Bean
public FilterRegistrationBean webStatFilter() {
    FilterRegistrationBean bean = new FilterRegistrationBean();
    bean.setFilter(new WebStatFilter());

    //exclusions:设置哪些请求进行过滤排除掉,从而不进行统计
    Map<String, String> initParams = new HashMap<>();
    initParams.put("exclusions", "*.js,*.css,/druid/*,/jdbc/*");
    bean.setInitParameters(initParams);

    //  "/*" 表示过滤所有请求
    bean.setUrlPatterns(Arrays.asList("/*"));
    return bean;
}
spring:
  datasource:
    username: root
    password: 1328910
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
    driver-class-name: com.mysql.cj.jdbc.Driver

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

    #配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
    #如果允许时报错  java.lang.ClassNotFoundException: org.apache.log4j.Priority
    #则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

整合mybatis

配置mbatis-spring-boot-starter

配置的mapper接口需要@Mapper

Dao层加个repository

  • @Component 是一个泛化的概念,仅仅表示一个组件 (Bean) ,可以作用在任何层次。
  • @Service 通常作用在业务层,但是目前该功能与 @Component 相同。
  • @Constroller 通常作用在控制层,但是目前该功能与 @Component 相同。

或者再springboot加载应用里加个@MapperScan(“com.lgd.mapper”)

Propertier中整合mybatis

mabatis.type-aliases-package = com.lgd.pojo

//(classpath指resources文件夹)

mybatis.mapper-locations = classpath:mybatis/mapper/*

SpringSecurity

引入spring-boot-starter-security

与shiro很像,认证,授权(vip1,vip2,vip3)

  • 功能权限
  • 访问权限
  • 菜单权限

@EnalbleWebSecurity

@Enablexxxxx 这个格式

安全:认证与授权

密码编码:passwordencoder,

BCrytPasswordEncoder,java原生md5,但是似乎已经不安全了

MD5+salt仍安全,

使用thymeleaf

<html lang="en" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
 <a class="item"  th:href="@{/index}">首页</a>

            <!--登录注销-->
            <div class="right menu">
                <!--未登录-->
                <div sec:authorize="!isAuthenticated()">
                    <a class="item" th:href="@{/toLogin}">
                        <i class="address card icon"></i> 登录
                    </a>
                </div>


                <!--注销-->
                <div sec:authorize="isAuthenticated()">
                    <a class="item">
                        用户名:<span sec:authentication="name"></span>
                        角色:<span sec:authentication="principal.authorities"></span>
                    </a>
                </div>

                <div sec:authorize="isAuthenticated()">
                    <a class="item" th:href="@{/logout}">
                        <i class="sign-out icon"></i> 注销
                    </a>
                </div>


                <!--已登录
                <a th:href="@{/usr/toUserCenter}">
                    <i class="address card icon"></i> admin
                </a>
                -->
            </div>
        </div>
    </div>
<!--根据权限来显示内容-->
<div class="column" sec:authorize="hasRole('vip1')">
                <div class="ui raised segment">
                    <div class="ui">
                        <div class="content">
                            <h5 class="content">Level 1</h5>
                            <hr>
                            <div><a th:href="@{/level1/1}"><i class="bullhorn icon"></i> Level-1-1</a></div>
                            <div><a th:href="@{/level1/2}"><i class="bullhorn icon"></i> Level-1-2</a></div>
                            <div><a th:href="@{/level1/3}"><i class="bullhorn icon"></i> Level-1-3</a></div>
                        </div>
                    </div>
                </div>
            </div>

总体就是,前端传uesrname和password和checkbox的remeberme三个变量

然后springsecurity可以设置获取的这三个变量的名称以及自己顶定制登陆页面和表单提交请求的url,

http.formLogin()
        .usernameParameter("username")
        .passwordParameter("password")
        .loginPage("/toLogin")//定制登陆页
        .loginProcessingUrl("/login"); // 登陆表单提交请求
http.csrf().disable();//关闭csrf功能:跨站请求伪造,默认只能通过post方式提交logout请求

        http.logout().logoutSuccessUrl("/");

        //记住我
        http.rememberMe().rememberMeParameter("remember");

shiro

依赖
<!-- https://mvnrepository.com/artifact/com.github.theborakompanioni/thymeleaf-extras-shiro -->
<dependency>
    <groupId>com.github.theborakompanioni</groupId>
    <artifactId>thymeleaf-extras-shiro</artifactId>
    <version>2.0.0</version>
</dependency>

<!--
Subject 用户
SecurityManager 管理所有用户
Realm 连接数据
-->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.12</version>
</dependency>

<!--shiro-->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.4.1</version>
</dependency>

<!--thymeleaf模板-->
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
</dependency>

<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
前端的使用示例
<div th:if="${session.loginUser==null}">
    <a th:href="@{/toLogin}">登录</a>
</div>
<div shiro:hasPermission="user:add">
    <a th:href="@{/user/add}">add</a>
</div>
<div shiro:hasPermission="user:update">
    <a th:href="@{/user/update}">update</a>
</div>
shiroconfig基本配置参考实例
@Configuration
public class ShiroConfig {

    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setSecurityManager(defaultWebSecurityManager);
        //添加shiro的内置过滤器
        /*
            anon:无需认证就能访问
            authc:必须认证才能访问
            user:必须拥有记住我功能才能访问
            perms:拥有某个资源的权限才能访问
            role:拥有某个角色权限才能访问
         */
        //拦截
        Map<String,String> filter = new LinkedHashMap<>();

        //授权
        filter.put("/user/add","perms[user:add]");
        filter.put("/user/update","perms[user:update]");
        //登录的请求
        bean.setLoginUrl("/toLogin");
        //未授权的请求
        bean.setUnauthorizedUrl("/noauth");

        bean.setFilterChainDefinitionMap(filter);

        return bean;
    }

    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        defaultWebSecurityManager.setRealm(userRealm);

        return defaultWebSecurityManager;
    }

    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }

    //整合shiroDialect:用来整合shiro thymeleaf
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }
}
UserRealm,授权认证实例
public class UserRealm extends AuthorizingRealm {

   @Autowired
    UseraService useraService;

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了授权");

        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();

        //info.addStringPermission("user:add");
        //拿到当前用户登陆对象
        Subject subject= SecurityUtils.getSubject();
        Usera currentUser= (Usera) subject.getPrincipal();//拿到User对象
        info.addStringPermission(currentUser.getPerms());//设置当前用户对象

        return info;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行了认证");

        //用户名,密码,数据库中获取
        Usera usera = null;
        UsernamePasswordToken userToken=(UsernamePasswordToken) authenticationToken;
        try {
            usera = useraService.queryByName(userToken.getUsername());//获取用户名
        }catch (Exception e){
            System.out.println(e);
        }
        if(usera==null){//说明查无此人
            return null;
        }
        String name= usera.getName();
        String password = usera.getPwd();
        //密码认证,shiro做
        return new SimpleAuthenticationInfo(usera,password,"");//放入User对象
    }
}

Swagger 2021/10/27

依赖
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<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>
配置
@Configuration
@EnableSwagger2
///swagger-ui.html
public class SwaggerConfig {
    @Bean
    public Docket createRestApi(Environment environment) {
        //获取要显示的swagger的环境
        Profiles profiles=Profiles.of("dev","test");

        //获取当前项目环境是否为指定环境
        Boolean flag=environment.acceptsProfiles(profiles);

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                //设置分组
                .groupName("lgd")
                //是否启用Swagger,false则不能浏览器访问
//                .enable(flag)
                .select()// 通过.select()方法,去配置扫描接口,RequestHandlerSelectors配置如何扫描接口

                //指定要扫描的包
                /*
                any() // 扫描所有,项目中的所有接口都会被扫描到
                none() // 不扫描接口
                // 通过方法上的注解扫描,如withMethodAnnotation(GetMapping.class)只扫描get请求
                withMethodAnnotation(final Class<? extends Annotation> annotation)
                // 通过类上的注解扫描,如.withClassAnnotation(Controller.class)只扫描有controller注解的类中的接口
                withClassAnnotation(final Class<? extends Annotation> annotation)
                basePackage(final String basePackage) // 根据包路径扫描接口
                 */
                为当前包路径
                .apis(RequestHandlerSelectors.basePackage("com.lgd.controller"))
                .paths(PathSelectors.any())
                //过滤路径
//                .paths(PathSelectors.ant("/lgd/**"))
                .build();
    }

    private ApiInfo apiInfo() {
        Contact contact = new Contact("lgd","https://www.zust.edu.cn","2709296991@qq.com");
        return new ApiInfoBuilder()
                .title("接口文档")
                .description("lgd学习swagger")
                .contact(contact)
                .termsOfServiceUrl("https://www.zust.edu.cn")
                .version("1.0")
                .build();
    }
}

分布式,异步处理

异步任务

所在方法@Async

Application 上@EnableAsync

多线程

定时任务 timer

邮件发送

mail的配置

spring.mail.username=1017276522@qq.com
spring.mail.password=dedjgrzqiskubdij
spring.mail.host=smtp.qq.com
spring.mail.properties.mail.smtp.ssl.enable=true
@Autowired
    JavaMailSender javaMailSender;

    @Test
    void contextLoads() {

        SimpleMailMessage mailMessage=new SimpleMailMessage();
        mailMessage.setSubject("你好JavaMailSender");
        mailMessage.setText("hello world!!!");

        mailMessage.setTo("1017276522@qq.com");
        mailMessage.setFrom("1017276522@qq.com");
//        for (int i = 0; i < 2; i++) {
            javaMailSender.send(mailMessage);
//        }
    }

    @Test
    public void contextLoads2() throws MessagingException {
        //邮件设置2:一个复杂的邮件
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);

        helper.setSubject("通知-明天来狂神这听课");
        helper.setText("<b style='color:red'>今天 7:30来开会</b>",true);

        //发送附件
        //helper.addAttachment("1.jpg",new File(""));
        //helper.addAttachment("2.jpg",new File(""));

        helper.setTo("2622046365@qq.com");
        helper.setFrom("2622046365@qq.com");

        javaMailSender.send(mimeMessage);
    }
定时任务

@EnableScheduling //开始定时功能

TaskScheduler 任务调度者

TaskExecutor 任务执行者

Cron表达式

16:34.40

@Scheduled(cron = "40 34 16 * * ?")
public void Hellos(){
    SimpleDateFormat df = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
    System.out.println("执行成功,现在是" +df.format(new Date()));
}

Springboot继承Redis

留着学完Redis再来看 = =

分布式 Dubbo + Zookeeper + SpringBoot

Netty网络框架,约一个月,里头需要学习计算机网络

Zookeeper:

下载地址:https://dlcdn.apache.org/zookeeper/zookeeper-3.7.0/

简单部署教程:(需要系统配置JAVA_HOME变量)

https://blog.youkuaiyun.com/qq_33316784/article/details/88563482

npm镜像配置:

$ npm config set registry https://registry.npm.taobao.org
$ npm info underscore (如果上面配置正确这个命令会有字符串response)

springboot读取resources文件夹下边的文件
//第一种方法
File file =  ResourceUtils.getFile("classpath:template/科研项目模板.xlsx");
//获取文件的相对路径  可在控制台打印查看输出结果
String filePath = ResourceUtils.getFile("classpath:template/科研项目模板.xlsx").getPath();
//第二种方法
//直接将目标文件读成inputstream  this指当前类的实例对象
InputStream ins = this.getClass().getClassLoader().getResourceAsStream("template/科研项目模板.xlsx");
File file = new File(ins);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值