SpringBoot学习笔记

1.1、简介

springBoot优点

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

微服务:https://www.cnblogs.com/liuning8023/p/4493156.html

个人理解:微服务,是将一个整体程序拆分成很多部分(服务),这些服务改动后,只需要局部更新,不用更新整体。单个服务编程语言、数据库不同,也可以互相连接。

生成springboot

  1. 在官网生成,生成后导入:https://start.spring.io

    Dependencies要加上Spring Web

  2. 在idea生成:新建项目>Spring Initializr即可

分析

<!--web依赖-->		
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--单元测试-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<!--打jar包插件-->
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

所以spring依赖都是通过spring-boot-starter这个开头的

打jar包,点maven的Lifecycle下的package

运行:java -jar *.jar

1.2、springBoot自动装配原理

启动器

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
  • 启动器是springboot的启动场景
  • 比如spring-boot-starter-web,会自动导入关于web依赖
  • springboot会将所有场景功能,变成一个个启动器
  • 要使用什么功能,只需要找到对应启动器

主程序

//SpringBootApplication 标注这个类是一个springboot的应用
@SpringBootApplication
public class Springboot01HelloworldApplication {
	public static void main(String[] args) {
	    //将springboot应用启动
	    SpringApplication.run(Springboot01HelloworldApplication.class, args);
	}
}
  • 注解

    @SpringBootConfiguration : springboot的配置
        @Configuration:spring配置类
        @Component:说明这也是一个spring组件
        
    @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(getSpringFactoriesLoaderFactoryClass(),
                                                                             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;
    }
    

1.3、yaml配置详解

#对空格要求严格
#回车号代表是上级的子属性
server:
  port: 8081

#对象
student:
  name: zhang
  age: 22

#行内写法
studentInfo: {name: zhang,age: 33}

#数组
pets:
  - cat
  - dog
  - pig

#数组行内写法
petArr: [cat,dog,pig]

1.4、绑定配置文件值的几种方式

第一种(读取spring配置文件)

@ConfigurationProperties(prefix = "person")
person:
  name: 张三{$random.uuid}
  age: 22
  happy: false
  brith: 2020/01/01

第二种(读取指定配置文件)

@PropertySource(value = "classpath:zhang.properties")
public class Person {
    //SPEL表达式取出配置文件中的值
    @Value("${name}")
name=张三

两种方式对比

ConfigurationProperties PropertySource
批量注入属性 支持 不支持,需要@Value一个个注入
松散绑定 支持 firstName识别first-name 不支持
SpEL 不支持 支持
JSR303数据校验 支持 不支持
复杂类型封装 支持 不支持

结论:

  • 需要注入很多属性时,且yml与properties都支持时,用ConfigurationProperties较好
  • 注入单个属性时,@Value的方式较好
  • 如果单独编写了一个配置文件,用PropertySource较好

1.5、JSR303

核心类

用法

@Validated
public class Person {
    //SPEL表达式取出配置文件中的值
//    @Value("${name}")

    @Email(message = "邮箱错误")

1.6、多环境配置

properties多环境配置

application.properties

#多环境配置
spring.profiles.active=dev

application-dev.properties

server.port=8081

application-test.properties

server.port=8082

yml多环境配置

application.yml

spring:
  profiles:
    active: dev  #环境

application-dev.yml

server:
  port: 8084

application-test.yml

server:
  port: 8082

1.7、自动装配原理再解析

个人理解:配置文件中的属性,都是一个个的类组件,Springboot将这些类装配管理。在配置文件设置属性后,直接影响类中的属性。

1.8、静态资源导入方式

webjars方式导入:

WebJars - Web Libraries in Jars中找到资源包,然后在maven中引入,如导入jquery

<dependency>
    <groupId>org.webjars.npm</groupId>
    <artifactId>jquery</artifactId>
    <version>3.6.0</version>
</dependency>

使用:localhost:8080/webjars/jquery/3.6.0/jquery.js

文件方式导入:

在resources下,public/static/resources都是可以被web访问的,访问优先级rescourse>static(默认使用)>public

使用:localhost:8080/*

1.9、thymeleaf模板引擎

官网文档:https://www.thymeleaf.org/

引入maven

<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
    <version>3.0.14.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-java8time</artifactId>
    <version>3.0.4.RELEASE</version>
</dependency>

Controller

@RequestMapping("/index")
public String index() {
    return "index";
}

templates下创建index.html

public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";

语法

使用前,需要在html中引入

<html xmlns:th="http://www.thymeleaf.org">

纯文本方式一

<span th:text="${msg}"></span>

纯文本方式二

[[${msg}]]

可解析Html的文本

<span th:utext="${msg}"></span>

循环

model.addAttribute("userList", Arrays.asList("zhang", "san"));
<div th:each="user:${userList}" th:text="${user}"></div>
<div th:each="user:${userList}">[[${user}}]]</div>

if条件判断

<span th:if="${msg} == '<h1>ok</h1>'">
    true
</span>
<span th:if="${msg} != '<h1>ok</h1>'">
    false
</span>

引入文件

th:fragment="sidebar" 标记块

th:insert="dashboard" 引入文件的标记块

th:replace="~{commons/commons::sidebar(active='main.html')}" 也是引入,可以传参

1.10、国际化

  1. Settings->File Encodings的三个编码要改成UTF-8

  2. 在resources下新建i18n文件夹,再新建login.properties、login_zh_CN.properties、login_en_US.properties。

  3. 配置多语言

    login.properties

    login.password=密码  #默认
    

    login_zh_CN.properties

    login.password=密码  #中文
    

    login_en_US.properties

    login.password=password   #英文
    
  4. 在application.properties中配置多语言

    #多语言路径
    spring.messages.basename=i18n.login
    
    
  5. 测试

    <li><input name="" type="text" class="loginpwd" th:value="#{login.password}" onclick="JavaScript:this.value=''"/>
    
  6. 语言切换前端

    <div class="loginbm">
        <a href="login.html?l=zh_CN">中文</a>
        <a href="login.html?l=en_US">英文</a>
    </div>
    
  7. 后端解析语言切换

    MyLocaleResolver.java 自定义组件

    package com.zhang.config;
    
    import org.springframework.web.servlet.LocaleResolver;
    import org.thymeleaf.util.StringUtils;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.Locale;
    
    public class MyLocaleResolver implements LocaleResolver {
    
        //解析请求
        @Override
        public Locale resolveLocale(HttpServletRequest request) {
            //获取请求中的语言参数
            String language = request.getParameter("l");
            //如果没有就使用默认的
            Locale locale = Locale.getDefault();
            //如果请求带了国际化的参数
            if (!StringUtils.isEmpty(language)){
                //zh_CN
                String[] s = language.split("_");
                //国家,地区
                return new Locale(s[0], s[1]);
            }
            return locale;
        }
    
        @Override
        public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
    
        }
    }
    

MyMvcConfig.java 将组件配置到Spring容器中

package com.zhang.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.Locale;

/**
 * @author zhangxiny
 * @apiNote
 * @date 2022-01-14 17:10
 */
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

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

1.11、登录拦截器

自定义拦截器 LoginHandlerInterceptor.java

package com.zhang.config;

import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class LoginHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        Object userInfo = session.getAttribute("userInfo");
        if (userInfo!=null) {
            return true;
        }
        request.setAttribute("msg", "没有权限,请先登录");
        request.getRequestDispatcher("/login").forward(request, response);
        return false;
    }
}

MyMvcConfig.java 将拦截器重写到Spring容器中

package com.zhang.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.Locale;

/**
 * @author zhangxiny
 * @apiNote
 * @date 2022-01-14 17:10
 */
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    //配置拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/login", "/user/login", "/login.html", "/css/**", "/js/**", "/images/**");
    }
}

1.12、Druid

  1. 引入包

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.2.8</version>
    </dependency>
    
  2. 配置后台监控

    config/DruidConfig.java

    package com.zhang.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.servlet.Filter;
    import javax.servlet.Servlet;
    import javax.sql.DataSource;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * @author zhangxiny
     * @apiNote
     * @date 2022-01-19 15:26
     */
    @Configuration
    public class DruidConfig {
    
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource")
        public DataSource druidDataSource() {
            return new DruidDataSource();
        }
    
        /**
         * 后台监控
         * @return ServletRegistrationBean
         */
        @Bean
        public ServletRegistrationBean statViewServlet() {
            ServletRegistrationBean<Servlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
    
            //后台需要有人登录,账号密码配置
            Map<String, String> map = new HashMap<String, String>(3);
    
            //增加配置
            map.put("loginUsername", "root");
            map.put("loginPassword", "root");
    
            //允许谁可以访问
            map.put("allow", "");
            bean.setInitParameters(map);
            return bean;
        }
    }
    
  3. 打开Druid面板

    http://localhost:8080/druid/

1.13、整合mybatis

  1. 导入包

    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.1</version>
    </dependency>
    
  2. 在springboot配置文件中配置mybatis

    spring.datasource.username=root
    spring.datasource.password=root
    spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    
    #mybatis
    mybatis.type-aliases-package=com.zhang.pojo
    mybatis.mapper-locations=classpath:mapping/*.xml
    

1.14、SpringSecurity

Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架

  1. 引入包(springboot版本2.0.9.RELEASE)

    <!--SpringSecurity-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
        <version>2.1.6.RELEASE</version>
    </dependency>
    
    <!--security与thymeleaf的整合-->
    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-springsecurity4</artifactId>
        <version>3.0.4.RELEASE</version>
    </dependency>
    
  2. 配置访问权限及登录认证权限 com.zhang.config.SecurityConfig.java

    package com.zhang.config;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    
    @Configuration
    @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();
            //开启注销并指定跳转页面
            http.logout().logoutSuccessUrl("/");
        }
    
        //认证
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                    .withUser("zhangsan").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2", "vip3")
                    .and()
                    .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2", "vip3")
                    .and()
                    .withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
        }
    }
    
    
  3. html页面

    <html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.w3.org/1999/xhtml">
        <!--如果未登录-->
        <a sec:authorize="!isAuthenticated()" th:href="@{/login}">登录</a>
        <!--如果登录,用户名-->
        <span sec:authorize="isAuthenticated()" >
        <a th:href="@{/logout}">
            用户名:<span sec:authentication="name"></span>
            注销
        </a>
            </span>
        <ul sec:authorize="hasRole('vip1')">
            <li><a href="/level1/1">level1-1</a></li>
            <li><a href="/level1/2">level1-2</a></li>
            <li><a href="/level1/3">level1-3</a></li>
        </ul>
        <ul sec:authorize="hasRole('vip2')">
            <li><a href="/level2/1">level2-1</a></li>
            <li><a href="/level2/2">level2-2</a></li>
            <li><a href="/level2/3">level2-3</a></li>
        </ul>
        <sec:authorize url="/level3/">
        <ul>
            <li><a href="/level3/1">level3-1</a></li>
            <li><a href="/level3/2">level3-2</a></li>
            <li><a href="/level3/3">level3-3</a></li>
        </ul>
        </sec:authorize>
    </html>
    

1.15、Shiro

SpringBoot整合Shrio、环境搭建、登录拦截、用户认证、整合Mybatis、请求授权实现、整合Thymeleaf,详见压缩包。

https://zxy-me.oss-cn-beijing.aliyuncs.com/note/springboot-08-shiro.zip

测试环境步骤:

  1. 导入依赖

  2. 配置shiro.ini

  3. 运行Quickstart

1.16、Swagger

  1. 引入依赖

     <dependency>
         <groupId>io.springfox</groupId>
         <artifactId>springfox-swagger-ui</artifactId>
         <version>2.9.2</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.9.2</version>
    </dependency>
    
  2. 编写配置类

    package com.zhang.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.env.Environment;
    import org.springframework.core.env.Profiles;
    import springfox.documentation.builders.PathSelectors;
    import springfox.documentation.builders.RequestHandlerSelectors;
    import springfox.documentation.service.ApiInfo;
    import springfox.documentation.service.Contact;
    import springfox.documentation.service.VendorExtension;
    import springfox.documentation.spi.DocumentationType;
    import springfox.documentation.spring.web.plugins.Docket;
    import springfox.documentation.swagger2.annotations.EnableSwagger2;
    
    import java.util.ArrayList;
    
    import static springfox.documentation.service.ApiInfo.DEFAULT_CONTACT;
    
    /**
     * @author zhangxiny
     * @apiNote
     * @date 2022-02-08 10:28
     */
    @Configuration
    @EnableSwagger2  //开启swagger2
    public class SwaggerConfig {
    
        //配置了swagger的docket bean实例
        @Bean
        public Docket docket(Environment environment) {
    
            //设置要显示的dev环境
            Profiles profiles = Profiles.of("dev");
            boolean flag = environment.acceptsProfiles(profiles);
    
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    //是否启动swagger
                    .enable(flag)
                    .select()
                    //RequestHandlerSelectors 配置要扫描接口的方式
                    //basePackage 指定要扫描的包(通常用这个)
                    //any 扫描全部
                    //none 不扫描
                    //withClassAnnotation 扫描类上的注解 RestController.class
                    //withMethodAnnotation 扫描方法上的注解 GetMapping.class
                    .apis(RequestHandlerSelectors.basePackage("com.zhang.controller"))
                    //不扫描某个包
                    //.paths(PathSelectors.ant("/zhang/**"))
                    .build();
        }
    
        //配置swagger信息
        private ApiInfo apiInfo(){
            Contact contact = new Contact("Zhang", "http://www.zhangxiny.com", "123456@qq.com");
            return new ApiInfo(
                    "API接口文档",
                    "备注说明",
                    "1.0",
                    "urn:tos",
                    contact,
                    "Apache 2.0",
                    "http://www.apache.org/licenses/LICENSE-2.0",
                    new ArrayList<VendorExtension>());
        }
    }
    
  3. 分组与接口注释

    • 分组

      @Bean
      public Docket docket1(){
          return new Docket(DocumentationType.SWAGGER_2).groupName("A");
      }
      
      @Bean
      public Docket docket2(){
          return new Docket(DocumentationType.SWAGGER_2).groupName("B");
      }
      
      @Bean
      public Docket docket3(){
          return new Docket(DocumentationType.SWAGGER_2).groupName("C");
      }
      
    • API注释

      @ApiOperation("测试3")
      @PostMapping("/hello3")
      public User hello3(User user){
          return user;
      }
      
    • 参数注释

      @ApiOperation("hello2")
      @GetMapping("/hello2")
      public String hello2(@ApiParam("用户名") String username){
          return "hello2" + username;
      }
      
    • 实体类及参数注释

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

总结:

  • 文档实时更新
  • 可以在线测试

1.17、异步任务(不阻塞)

  1. springboot启动类开启异步任务

    //开启
    @EnableAsync
    @SpringBootApplication
    public class Springboot09TestApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(Springboot09TestApplication.class, args);
        }
    
    }
    
  2. 给需要使用的方式加上注解

    @Async
    public void hello(){
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("数据正在处理中");
    }
    

1.18、邮件发送

  1. 依赖

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

    spring.mail.username=123@qq.com
    spring.mail.password=sjntvltpkdyudagc(邮箱服务商的设置中得到smtp密钥)
    spring.mail.host=smtp.qq.com
    #开启加密验证
    spring.mail.properties.mail.smtp.ssl.enable=true
    
  3. 测试类

    
    @Test
    void contextLoads() {
        //简单邮件
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setSubject("标题");
        simpleMailMessage.setText("内容");
        simpleMailMessage.setTo("123@qq.com");
        simpleMailMessage.setFrom("123@qq.com");
        mailSender.send(simpleMailMessage);
    }
    
    @Test
    void contextLoads2() throws MessagingException {
        //复杂邮件
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        //组装
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
    
        //正文
        helper.setSubject("邮件标题哦");
        helper.setText("<p style='color:red;'>邮件正文内容哦</p>", true);
    
        //附件
        helper.addAttachment("a.doc", new File("I:\\a.doc"));
        helper.addAttachment("b.doc", new File("I:\\b.doc"));
    
        helper.setTo("123@qq.com");
        helper.setFrom("123@qq.com");
        mailSender.send(mimeMessage);
    }
    

1.19、定时任务

  1. 启动类开启注解

    //开启
    @EnableScheduling
    @SpringBootApplication
    public class Springboot09TestApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(Springboot09TestApplication.class, args);
        }
    
    }
    
  2. 测试类

    package com.zhang.service;
    
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Service;
    
    @Service
    public class ScheduledService {
    
        //在一个特定的时间执行这个方法
        //cron表达式
        //秒 分 时 日 月
    
        //每天20点22分执行一次
        //@Scheduled(cron = "0 22 20 * * ?")
    
        //每两秒执行一次
        @Scheduled(cron = "0/2 * * * * ?")
        public void hello(){
            System.out.println("这个方法被执行了");
        }
    }
    
    

1.20、springboot集成redis

  1. 导入依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
  2. 添加配置

    #配置redis
    spring.redis.host=127.0.0.1
    spring.redis.port=6379
    
  3. 测试

    
    @Test
    void contextLoads() {
        //        redisTemplate.opsForValue(); //操作字符串
        //        redisTemplate.opsForList();  //操作数组
        //        redisTemplate.opsForSet();
        //        redisTemplate.opsForHash();
        //        redisTemplate.opsForZSet();
        //        redisTemplate.opsForGeo();
        //        redisTemplate.opsForHyperLogLog();
    
        //获取redis连接
        //        RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
        //        connection.flushDb();
        //        connection.flushAll();
    
        redisTemplate.opsForValue().set("key", "张三");
        System.out.println(redisTemplate.opsForValue().get("key"));
    }
    

1.21、分布式系统理论

将服务部署到多个主机上,使用nginx代理服务器转发到具体的主机,主机的数据存储、缓存,可以用云数据库、云redis实现。

1.22、Zookeeper + dubbo-admin实现服务注册、调用与监控

  1. zookeeper

    • 在官网下载:Apache ZooKeeper

    • 下载后,conf目录下zoo_sample.cfg文件名改成zoo.cfg

    • 在bin中使用cmd启动zkServer.cmd

  2. dubbo-admin(监控中心)

  3. 编写服务提供者与消费者两个demo

1.22、总结

  1. Spring

    ​ IOC:Spring集中管理对象,使用时不需要再初始化,直接使用注解注入即可。

    ​ AOP:给原来的业务增加功能,但代码逻辑不会对原业务有任何影响,实现了解耦合,如日志等。

  2. 微服务

    ​ 当用户量非常大,一台服务器无法应对压力时。可以将程序拆分成多个服务,每个服务互不影响,并可以部署在不同的服务器上。

    ​ 技术:

    ​ Spring Cloud NetFlix

    ​ Apache Dubbo zookeeper

    ​ Spring Cloud Alibaba

posted @   zhangxiny  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
点击右上角即可分享
微信分享提示