springboot

springboot 集成 mybats swagger redis pageHelper nacos backlog…

redis 序列化 fastjson序列化漏洞 根据包名序列化 ,反序列化时包路径不同容易引起报错
spring aop ioc
springboot 自动装配 自定义配置
springboot …


在这里插入图片描述

前言

提示:这里可以添加本文要记录的大概内容:

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、创建sprngboot项目 集成 mybatis

  1. 导入依赖 常用依赖
<!--    web start 链接  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
<!--     mysql 链接  -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <!-- <version>5.1.4</version> -->
        </dependency>
        <!--     Table -->
        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>persistence-api</artifactId>
            <version>1.0</version>
        </dependency>
                <!--mapper-->
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper</artifactId>
            <version>4.1.5</version>
        </dependency>
        
        <!--        lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--    junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.1</version>
            <scope>test</scope>
        </dependency>
<!--       swagger -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.1</version>
        </dependency>
  1. 导入m ybatis 依赖
<!--     mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>
  1. 链接数据库 mybatis配置 文件

server:
  port: 8091
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mydb
    password: root
    username: root
mybatis:
  mapper-locations: classpath:mappper/*.xml
  type-aliases-package: com.ycy.pojo
  configuration:
    log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl

4.添加maper 工具类

package com.ycy.util;


import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;

public interface MyMapper<T> extends Mapper<T>, MySqlMapper<T> {
   
}

  1. 编写实体类
package com.ycy.pojo;

import com.github.pagehelper.Page;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.Id;
import javax.persistence.Table;


@ApiModel("用户")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "user")
public class User extends Page {
    @ApiModelProperty(value = "id 主键")
    @Id
    private String id;
    @ApiModelProperty("姓名")
    private String name;
    @ApiModelProperty("年龄")
    private int age;
    @ApiModelProperty(value = "生日")
    private String birthday;
    @ApiModelProperty(value = "公司")
    private String company;

}

  1. mapper
package com.ycy.mapper;

import com.ycy.pojo.UserModel;
import com.ycy.util.MyMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * @author: luck
 * @date: 2023/10/28 10:46
 * @Description:
 */
@Mapper
public interface UserMapper extends MyMapper<UserModel> {
    public List<UserModel> page(@Param("company") String company);
}


  1. service
package com.ycy.service;

import com.ycy.pojo.User;

import java.util.List;

/**
 * @author: luck
 * @date: 2023/10/28 10:45
 * @Description:
 */
public interface UserService {
    public List<User> page(String name);
    public void insert(User user);
    public void delete(String id);
    public void update(User user);
}

  1. serviceImpl
package com.ycy.service.impl;

import com.ycy.mapper.UserMapper;
import com.ycy.pojo.User;
import com.ycy.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author: luck
 * @date: 2023/10/28 11:22
 * @Description:
 */

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserMapper userMapper;

    @Override
    public List<User> page(String name) {
        return null;
    }

    @Override
    public void insert(User user) {
        userMapper.insert(user);
    }

    @Override
    public void delete(String id) {
        userMapper.deleteByPrimaryKey(id);
    }

    @Override
    public void update(User user) {
        userMapper.updateByPrimaryKey(user);
    }
}

  1. controller
package com.ycy.controller;

import com.ycy.pojo.User;
import com.ycy.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Api("用户")
@RestController
@RequestMapping("/hello")
public class HelloController {

    @Autowired
    UserService userService;

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

    @ApiOperation("分页查询用户")
    @RequestMapping("/page")
    public List<User> page(String name){
      return  userService.page(name);
    }

    @ApiOperation("添加用户")
    @PostMapping("/insert")
    public void insert(@RequestBody User user){
        userService.insert(user);
    }
}

二 集成 swagger

  1. 导入依赖
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
            <exclusions>
                <exclusion>
                    <groupId>io.swagger</groupId>
                    <artifactId>swagger-models</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.1</version>
        </dependency>

        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-models</artifactId>
            <version>1.5.21</version>
        </dependency>
  1. 创建配置文件 配置swagger
package com.ycy.config;

import io.swagger.annotations.Api;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.stereotype.Component;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
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 {

    public Docket docker(Environment environment){
        // 根据项目环境选择接口开放
        Profiles of = Profiles.of("dev", "test");
        boolean flag = environment.acceptsProfiles(of);

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiinfo())
                .groupName("ycy")
                .enable(flag)
                .select()
                .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))//这是注意的代码
                .paths(PathSelectors.any())
                .build();
    }

    public Docket docker2(Environment environment){
        // 根据项目环境选择接口开放
        Profiles of = Profiles.of("dev", "test");
        boolean flag = environment.acceptsProfiles(of);

        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("ycy");

    }

    private ApiInfo apiinfo(){
        Contact DEFAULT_CONTACT = new Contact("", "", "");
        return new ApiInfo(
                "Api Documentation  TEST ",
                "Api Documentation TEST",
                "1.0",
                "urn:tos",
                DEFAULT_CONTACT,
                "Apache 2.0",
                "http://www.apache.org/licenses/LICENSE-2.0",
                new ArrayList()
        );
    }
}


  1. 启动项添加 使用注解
package com.ycy;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@SpringBootApplication
@MapperScan("com.ycy.mapper")
@EnableSwagger2
public class SwaggerApplication {

    public static void main(String[] args) {
        SpringApplication.run(SwaggerApplication.class, args);
    }

}

效果
在这里插入图片描述

三 使用 pageHelper 分页

  1. 导入依赖
	<!--        pageHelper-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.4.6</version>
        </dependency>
  1. 创建 PageParam 工具类方便使用 不一定必备
package com.ycy.util;

import io.swagger.annotations.ApiModelProperty;

/**
 *
 * @author: luck
 * @Description: 分页参数
 *
 */
public class PageParam {

    @ApiModelProperty(value = "pageNum", dataType = "Integer", name = "pageNum", example = "1", required=true)
    private Integer pageNum=1;

    @ApiModelProperty(value = "pageSize", dataType = "Integer", name = "pageSize", example = "10", required=true)
    private Integer pageSize=10;

    public Integer getPageNum() {
        return pageNum;
    }

    public void setPageNum(Integer pageNum) {
        this.pageNum = pageNum;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }
}
  1. 在 查找数据时使用 ,比如在 UserServiceImpl 中使用
package com.ycy.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ycy.mapper.UserMapper;
import com.ycy.param.UserSelectParam;
import com.ycy.pojo.UserModel;
import com.ycy.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author: luck
 * @date: 2023/10/28 11:22
 * @Description:
 */

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserMapper userMapper;

    @Override
    public PageInfo<UserModel> page(UserSelectParam param) {
        PageHelper.startPage(1, 5);
        // startPage() 方法后面紧跟的这个查询就是一个分页查询.
        List<UserModel> list = userMapper.page(param.getCompany());
        // 使用 pageInfo 包装查询后的结果, 封装了十分详细的分页信息, 包括有查询出来的数据, 传入连续显示的页数, .....
        // 参数1: 要显示的数据. 参数2: 页码下标连续显示几页.
        PageInfo<UserModel> page = new PageInfo<>(list,5);
        return page;
    }

    @Override
    public void insert(UserModel userModel) {
        userMapper.insert(userModel);
    }

    @Override
    public void delete(String id) {
        userMapper.deleteByPrimaryKey(id);
    }

    @Override
    public void update(UserModel userModel) {
        userMapper.updateByPrimaryKey(userModel);
    }
}

  1. controller 层 使用
package com.ycy.controller;

import com.github.pagehelper.PageInfo;
import com.ycy.param.UserSelectParam;
import com.ycy.pojo.UserModel;
import com.ycy.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@Api(value = "用户管理",tags = "用户管理")
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    UserService userService;

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

    @ApiOperation(value = "分页查询用户")
    @PostMapping("/page")
    public PageInfo<UserModel> page(@RequestBody UserSelectParam param){
        return userService.page(param);
    }

    @ApiOperation(value = "添加用户")
    @PostMapping("/insert")
    public void insert(@RequestBody UserModel userModel){
        userService.insert(userModel);
    }
}

  1. 结果
    在这里插入图片描述

四 配置durld 数据库连接池

  1. 添加依赖
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.18</version>
        </dependency>
  1. yml 文件中配置durld
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mydb?characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useCompression=true&useSSL=false&&allowMultiQueries=true&useUnicode=true&autoReconnect=true&serverTimezone=GMT%2B8
    password: root
    username: root
    druid:
      type: com.alibaba.druid.pool.DruidDataSource
      url: jdbc:mysql://localhost:3306/mydb?characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useCompression=true&useSSL=false&&allowMultiQueries=true&useUnicode=true&autoReconnect=true&serverTimezone=GMT%2B8
      username: root
      password: root
      # 连接池初始化连接数
      initial-size: 5
      # 连接池最大廉价而数
      max-active: 20
      # 连接池最小空闲连接数
      min-idle: 5
      # 连接池最大空闲连接数
      max-idle: 10
      # 获取连接时最大等待时间 (毫秒)
      max-wait: 60000
      # 间隔多久检测一次空闲连接(毫秒)
      time-between-eviction-runs-millis: 60000
      # 用于检测连接是否有效的sql语句
      validation-query: SELECT 1
      # 是否开启连接池的检测功能 在获取连接时检测连接是否有效
      test-on-return: true
      # 是否开启连接吃的检测功能 在归还连接时检测连接是否有效
      test-on-borrow: false
      # 是否缓存 PrepareStatement 对象
      pool-prepared-statements: true
      # 缓存 PrepareStatement 对象最大数量
      max-pool-prepared-statement-per-connection-size: 20
      # 配置监控统计用的 filter 允许监控统计
      filters: stat
      # 配置扩展属性 用于监控统计分析 sql性能
      connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMills=5000
  1. 项目启动时显示
    在这里插入图片描述
  2. 配置 druid 配置类 开启监控
package com.ycy.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.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: luck
 * @date: 2023/11/21 10:28
 * @Description:
 */

@Configuration
public class DruidConfig {

    // 以下 druid 方法配置会在 application.yml 中后半部分生效
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource(){
        return new DruidDataSource();
    }

    // 配置 druid 的监控
    public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
        Map<String,String> initParams = new HashMap<>();
        initParams.put("loginUsername","root");
        initParams.put("loginPassword","root");
        // 允许后台谁可以访问
        // 只允许本机访问
//        initParams.put("allow","localhost");
        // 允许所有访问
        initParams.put("allow","");
        bean.setInitParameters(initParams);
        return bean;
    }

    // 配置 web 监控过滤器
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());
        // exclusions 设置那些请求运行过滤除掉 从而进行统计
        Map<String,String> initParams = new HashMap<>();
        initParams.put("exclusions","*.js,*.css,*.png,/druid/*");
        bean.setInitParameters(initParams);
        bean.setUrlPatterns(Arrays.asList("/*"));
        return bean;
    }
}

待续 …

参考文献 druid 配置

五 Redis 配置

  1. 本地下载 redis
  2. 导入依赖
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.1.7.RELEASE</version>
        </dependency>
  1. 配置 redis
spring: 
  redis:
    host: 127.0.0.1
    port: 6379
  1. 使用
package com.ycy.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author: luck
 * @date: 2023/11/20 16:16
 * @Description:
 */

@Api(value = "redis",tags = "redis")
@RestController
@RequestMapping("/redis")
public class RedisController {

    @Autowired(required = false)
    private RedisTemplate redisTemplate;

    @ApiOperation(value = "测试redis")
    @PostMapping("/test")
    public String test(){
        redisTemplate.opsForValue().set("name","tom");
        return redisTemplate.opsForValue().get("name").toString();
    }

}

  1. 结果
    在这里插入图片描述

六 LOGBACK 打印 sql 语句

注意定义日志文件输出路径 默认 系统用户目录。修改自定义打印日志的文件目录 可注释可修改

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 默认的一些配置 -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>

       <!-- 定义应用名称,区分应用 -->
    <property name="APP_NAME" value="logback-test"/>
        <!-- 定义日志文件的输出路径 -->
    <property name="LOG_PATH" value="${user.home}/logs/${APP_NAME}"/>

        <!-- 定义日志文件名称和路径 -->
    <property name="LOG_FILE" value="${LOG_PATH}/application.log"/>
    <!-- 定义警告级别日志文件名称和路径 -->
    <property name="WARN_LOG_FILE" value="${LOG_PATH}/warn.log"/>
    <!-- 定义错误级别日志文件名称和路径 -->
    <property name="ERROR_LOG_FILE" value="${LOG_PATH}/error.log"/>
    <!-- 定义错误级别日志文件名称和路径 -->
    <property name="DEBUG_LOG_FILE" value="${LOG_PATH}/debug.log"/>

    <!-- 定义指定目录service日志文件名称和路径 -->
    <property name="SERVICE_LOG_FILE" value="${LOG_PATH}/service.log"/>
    <!-- 定义指定目录HTTP日志文件名称和路径 -->
    <property name="HTTP_PACKAGE_LOG_FILE" value="${LOG_PATH}/http-package.log"/>
    <!-- 定义指定类topic方式的日志文件名称和路径 -->
    <property name="HTTP_TOPIC_LOG_FILE" value="${LOG_PATH}/http-topic.log"/>

    <!-- 自定义控制台打印格式 -->
    <property name="FILE_LOG_PATTERN" value="%green(%d{yyyy-MM-dd HH:mm:ss.SSS}) [%blue(traceId: %X{traceId})] [%highlight(%thread)] ${PID:- } %logger{36} %-5level - %msg%n"/>




    <!-- 将日志滚动输出到application.log文件中 -->
    <appender name="APPLICATION"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 输出文件目的地 -->
        <file>${LOG_FILE}</file>
        <encoder>
            <!-- 使用默认的输出格式打印 -->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>

        <!-- 设置 RollingPolicy 属性,用于配置文件大小限制,保留天数、文件名格式 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 文件命名格式 -->
            <fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 文件保留最大天数 -->
            <maxHistory>7</maxHistory>
            <!-- 文件大小限制 -->
            <maxFileSize>50MB</maxFileSize>
            <!-- 文件总大小 -->
            <totalSizeCap>500MB</totalSizeCap>
        </rollingPolicy>
    </appender>


    <!-- 摘取出WARN级别日志输出到warn.log中 -->
    <appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${WARN_LOG_FILE}</file>
        <encoder>
            <!-- 使用默认的输出格式打印 -->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
        <!-- 设置 RollingPolicy 属性,用于配置文件大小限制,保留天数、文件名格式 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 文件命名格式 -->
            <fileNamePattern>${LOG_PATH}/warn.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 文件保留最大天数 -->
            <maxHistory>7</maxHistory>
            <!-- 文件大小限制 -->
            <maxFileSize>50MB</maxFileSize>
            <!-- 文件总大小 -->
            <totalSizeCap>500MB</totalSizeCap>
        </rollingPolicy>
        <!-- 日志过滤器,将WARN相关日志过滤出来 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>WARN</level>
        </filter>
    </appender>

    <!-- 摘取出ERROR级别日志输出到error.log中 -->
    <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${ERROR_LOG_FILE}</file>
        <encoder>
            <!-- 使用默认的输出格式打印 -->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
        <!-- 设置 RollingPolicy 属性,用于配置文件大小限制,保留天数、文件名格式 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 文件命名格式 -->
            <fileNamePattern>${LOG_PATH}/error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 文件保留最大天数 -->
            <maxHistory>7</maxHistory>
            <!-- 文件大小限制 -->
            <maxFileSize>50MB</maxFileSize>
            <!-- 文件总大小 -->
            <totalSizeCap>500MB</totalSizeCap>
        </rollingPolicy>
        <!-- 日志过滤器,将ERROR相关日志过滤出来 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
    </appender>

    <!-- 摘取出ERROR级别日志输出到Debug.log中 -->
    <appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${DEBUG_LOG_FILE}</file>
        <encoder>
            <!-- 使用默认的输出格式打印 -->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
        <!-- 设置 RollingPolicy 属性,用于配置文件大小限制,保留天数、文件名格式 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 文件命名格式 -->
            <fileNamePattern>${LOG_PATH}/debug.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 文件保留最大天数 -->
            <maxHistory>7</maxHistory>
            <!-- 文件大小限制 -->
            <maxFileSize>50MB</maxFileSize>
            <!-- 文件总大小 -->
            <totalSizeCap>500MB</totalSizeCap>
        </rollingPolicy>
        <!-- 日志过滤器,将ERROR相关日志过滤出来 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
    </appender>


    <!-- 配置控制台输出 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!-- 配置日志打印格式 -->
<!--            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] ${PID:- } %logger{36} %-5level - %msg%n</pattern>-->
            <!-- 使用默认的输出格式打印 -->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>

    <!-- 定义指定目录service的appender -->
    <appender name="SERVICE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${SERVICE_LOG_FILE}</file>
        <encoder>
            <!-- 使用默认的输出格式打印 -->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
        <!-- 设置 RollingPolicy 属性,用于配置文件大小限制,保留天数、文件名格式 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 文件命名格式 -->
            <fileNamePattern>${LOG_PATH}/service.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 文件保留最大天数 -->
            <maxHistory>7</maxHistory>
            <!-- 文件大小限制 -->
            <maxFileSize>50MB</maxFileSize>
            <!-- 文件总大小 -->
            <totalSizeCap>500MB</totalSizeCap>
        </rollingPolicy>
    </appender>

    <!-- 定义指定目录HTTP-PACKAGE的appender -->
    <appender name="HTTP-PACKAGE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${HTTP_PACKAGE_LOG_FILE}</file>
        <encoder>
            <!-- 使用默认的输出格式打印 -->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
        <!-- 设置 RollingPolicy 属性,用于配置文件大小限制,保留天数、文件名格式 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 文件命名格式 -->
            <fileNamePattern>${LOG_PATH}/http-package.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 文件保留最大天数 -->
            <maxHistory>7</maxHistory>
            <!-- 文件大小限制 -->
            <maxFileSize>50MB</maxFileSize>
            <!-- 文件总大小 -->
            <totalSizeCap>500MB</totalSizeCap>
        </rollingPolicy>
    </appender>

    <!-- 定义指定类topic的appender -->
    <appender name="HTTP-TOPIC" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${HTTP_TOPIC_LOG_FILE}</file>
        <encoder>
            <!-- 使用默认的输出格式打印 -->
<!--            <pattern>${CONSOLE_LOG_PATTERN}</pattern>-->
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
        <!-- 设置 RollingPolicy 属性,用于配置文件大小限制,保留天数、文件名格式 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 文件命名格式 -->
            <fileNamePattern>${LOG_PATH}/http-topic.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 文件保留最大天数 -->
            <maxHistory>7</maxHistory>
            <!-- 文件大小限制 -->
            <maxFileSize>50MB</maxFileSize>
            <!-- 文件总大小 -->
            <totalSizeCap>500MB</totalSizeCap>
        </rollingPolicy>
    </appender>

<!--    打印 sql  -->

    <appender name="APP_SQL" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--活动日志输出路径示例-->
        <file>${LOG_PATH}/sql.log</file>
        <append>true</append>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <!-- onMatch:意思是当前级别以及以上要怎么处理 -->
            <onMatch>ACCEPT</onMatch>
            <!-- onMismatch:意思是当前级别(不包括当前级别)以下要怎么处理 -->
            <onMismatch>DENY</onMismatch>
        </filter>
        <!--存档日志示例-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/%d{yyyy-MM-dd}/sql.%i.log
            </fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!--日志大小可自定义-->
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--存档天数可自定义-->
            <maxHistory>90</maxHistory>
        </rollingPolicy>
        <!--统一日志输出格式-->
        <encoder charset="UTF-8">
            <pattern>%date [%thread] %-5level %logger [%L] - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 配置扫描包路径,追加日志到service的appender中 -->
    <!--若是additivity设为true,则子Logger不止会在自己的appender里输出,还会在root的logger的appender里输出-->
    <logger name="com.ycy.service.UserService" level="INFO" additivity="true">
        <appender-ref ref="SERVICE"/>
    </logger>

    <!-- 配置扫描包路径,追加日志到HTTP-PACKAGE的appender中 -->
    <!--若是additivity设为true,则子Logger不止会在自己的appender里输出,还会在root的logger的appender里输出-->
    <logger name="com.ycy.config" level="INFO" additivity="false">
        <appender-ref ref="HTTP-PACKAGE"/>
    </logger>

    <!-- 配置扫描包路径,追加日志到HTTP-TOPIC的appender中 -->
    <!--若是additivity设为true,则子Logger不止会在自己的appender里输出,还会在root的logger的appender里输出-->
    <logger name="http-log" level="INFO" additivity="false">
        <appender-ref ref="HTTP-TOPIC"/>
    </logger>


    <!--
        <logger>用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender><logger>仅有一个name属性,
        一个可选的level和一个可选的addtivity属性。
        name:用来指定受此logger约束的某一个包或者具体的某一个类。
        level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
              如果未设置此属性,那么当前logger将会继承上级的级别。
    -->
    <!--
        使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:
        第一种把<root level="INFO">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息
        第二种就是单独给mapper下目录配置DEBUG模式,代码如下,这样配置sql语句会打印,其他还是正常DEBUG级别:
     -->
    <springProfile name="test">
        <!--可以输出项目中的debug日志,包括mybatis的sql日志-->
        <logger name="com.ycy.mapper" level="DEBUG" additivity="false">
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="APP_SQL"/>
        </logger>
    </springProfile>


    <!-- 配置输出级别,加入输出方式 -->
    <root level="INFO">
        <appender-ref ref="CONSOLE"/>
        <!-- 加入APPLICATION输出 -->
        <appender-ref ref="APPLICATION"/>
        <!-- 加入WARN日志输出 -->
        <appender-ref ref="WARN"/>
        <!-- 加入ERROR日志输出 -->
        <appender-ref ref="ERROR"/>
        <!-- 加入ERROR日志输出 -->
        <appender-ref ref="DEBUG"/>

    </root>
</configuration>

使用 阿里云存儲 oss ducket

  1. 前提条件 拥有阿里云存储服务 使用阿里云账号创建ducket,并配置 AccessKey
    [阿里云服务]https://www.aliyun.com/?spm=a2c4g.750001.J_4VYgf18xNlTAyFFbOuOQe.2.5f705155Di1lWx
  2. 导入依赖
<!--        阿里云 存储  -->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.8.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>
  1. 配置 阿里云连接 创造 application-oss.properties 配置文件
# 阿里云 地域属性
aliyun.endpoint=oss-cn-shenzhen.aliyuncs.com
# AK ID
aliyun.accessKeyId=自己的 AK ID
# AK KEY
aliyun.accessKeySecret=自己的 AK KEY
# 存储空间
aliyun.bucketName=luck1125-bucket
# 存储桶 地址
aliyun.urlPrefix=http://luck1125-bucket.oss-cn-shenzhen.aliyuncs.com
  1. 创建配置文件 生成 OssClient 对象
package com.ycy.config;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
/**
 * @desc
 *
 * @author gaojun
 * @email 15037584397@163.com
 */
@Configuration
@PropertySource(value = {"classpath:application-oss.properties"})
@ConfigurationProperties(prefix = "aliyun")
@Data
public class OssConfig {
    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;
    private String urlPrefix;
    @Bean
    public OSS oSSClient() {
        return new OSSClient(endpoint, accessKeyId, accessKeySecret);
    }
}

  1. 定义文件上传、下载等接口
package com.ycy.service;

import com.aliyun.oss.model.OSSObjectSummary;
import com.ycy.vo.FileUploadResult;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.List;

/**
 * @author: luck
 * @date: 2023/11/28 11:58
 * @Description:
 */
public interface FileUploadService {

    public FileUploadResult upload(MultipartFile uploadFile);

    public InputStream exportOssFile(String objectName);

    public FileUploadResult delete(String objectName);

    public List<OSSObjectSummary> list();

    public String exportFile(String objectName);

}
  1. 实现类
package com.ycy.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.ListObjectsRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import com.ycy.config.OssConfig;
import com.ycy.service.FileUploadService;
import com.ycy.vo.FileUploadResult;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.List;

//import org.joda.time.DateTime;

/**
 * @author: luck
 * @date: 2023/11/28 14:07
 * @Description:
 */
@Service
public class FileUploadServiceImpl implements FileUploadService {

    // 允许上传的格式
    private static final String[] IMAGE_TYPE = new String[]{".bmp", ".jpg",
            ".jpeg", ".gif", ".png",".webp",".txt"};
    @Autowired
    private OSS ossClient;
    @Autowired
    private OssConfig aliyunConfig;
    /**
     * @author gaojun
     * @desc 文件上传
     *  文档链接 https://help.aliyun.com/document_detail/84781.html?spm=a2c4g.11186623.6.749.11987a7dRYVSzn
     * @email 15037584397@163.com
     * @return
     */
    @Override
    public FileUploadResult upload(MultipartFile uploadFile) {
        String originalFilename = uploadFile.getOriginalFilename();
        // 校验图片格式
        boolean isLegal = false;
        for (String type : IMAGE_TYPE) {
            if (StringUtils.endsWithIgnoreCase(uploadFile.getOriginalFilename(), type)) {
                isLegal = true;
                break;
            }
        }
        //封装Result对象,并且将文件的byte数组放置到result对象中
        FileUploadResult fileUploadResult = new FileUploadResult();
        if (!isLegal) {
            fileUploadResult.setStatus("error");
            return fileUploadResult;
        }
        //文件新路径
        String fileName = uploadFile.getOriginalFilename();
        String filePath = getFilePath(fileName);
        // 上传到阿里云
        try {
            ossClient.putObject(aliyunConfig.getBucketName(), filePath, new
                    ByteArrayInputStream(uploadFile.getBytes()));
        } catch (Exception e) {
            e.printStackTrace();
            //上传失败
            fileUploadResult.setStatus("error");
            return fileUploadResult;
        }
        fileUploadResult.setStatus("done");
        fileUploadResult.setResponse("success");
        //this.aliyunConfig.getUrlPrefix() + filePath 文件路径需要保持数据库
        fileUploadResult.setName(this.aliyunConfig.getUrlPrefix() + filePath);
        fileUploadResult.setUid(String.valueOf(System.currentTimeMillis()));
        return fileUploadResult;
    }
    /**
     * @author gaojun
     * @desc 生成路径以及文件名 例如://images/2019/04/28/15564277465972939.jpg
     * @email 15037584397@163.com
     */
    private String getFilePath(String sourceFileName) {
//        DateTime dateTime = new DateTime();
//        return "images/" + dateTime.toString("yyyy")
//                + "/" + dateTime.toString("MM") + "/"
//                + dateTime.toString("dd") + "/" + System.currentTimeMillis() +
//                RandomUtils.nextInt(100, 9999) + "." +
//                StringUtils.substringAfterLast(sourceFileName, ".");

        return "images/" +"oo"
                + System.currentTimeMillis() +
                StringUtils.substringAfterLast(sourceFileName, ".");
    }
    /**
     * @author gaojun
     * @desc 查看文件列表
     * 文档链接 https://help.aliyun.com/document_detail/84841.html?spm=a2c4g.11186623.2.13.3ad5b5ddqxWWRu#concept-84841-zh
     * @email 15037584397@163.com
     */
    public List<OSSObjectSummary> list() {
        // 设置最大个数。
        final int maxKeys = 200;
        // 列举文件。
        ObjectListing objectListing = ossClient.listObjects(new ListObjectsRequest(aliyunConfig.getBucketName()).withMaxKeys(maxKeys));
        List<OSSObjectSummary> sums = objectListing.getObjectSummaries();


//        // ossClient.listObjects返回ObjectListing实例,包含此次listObject请求的返回结果。
//        ObjectListing objectListing = ossClient.listObjects(aliyunConfig.getBucketName());
//        // objectListing.getObjectSummaries获取所有文件的描述信息。
//        for (OSSObjectSummary objectSummary : objectListing.getObjectSummaries()) {
//            System.out.println(" - " + objectSummary.getKey() + "  " +
//                    "(size = " + objectSummary.getSize() + ")");
//        }
        return sums;
    }

    @Override
    public String exportFile(String objectName) {
        // 设置签名URL过期时间,单位为毫秒。本示例以设置过期时间为1小时为例。
        Date expiration = new Date(new Date().getTime() + 3600 * 1000L);
        // 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
        URL url = ossClient.generatePresignedUrl(aliyunConfig.getBucketName(), objectName, expiration);
        return url.toString();
    }

    /**
     * @author gaojun
     * @desc 删除文件
     * 文档链接 https://help.aliyun.com/document_detail/84842.html?spm=a2c4g.11186623.6.770.4f9474b4UYlCtr
     * @email 15037584397@163.com
     */
    @Override
    public FileUploadResult delete(String objectName) {
        ossClient.deleteObject(aliyunConfig.getBucketName(), objectName);
        FileUploadResult fileUploadResult = new FileUploadResult();
        fileUploadResult.setName(objectName);
        fileUploadResult.setStatus("removed");
        fileUploadResult.setResponse("success");
        return fileUploadResult;
    }
    /**
     * @author gaojun
     * @desc 下载文件
     * 文档链接 https://help.aliyun.com/document_detail/84823.html?spm=a2c4g.11186623.2.7.37836e84ZIuZaC#concept-84823-zh
     * @email 15037584397@163.com
     */
    @SneakyThrows
    @Override
    public InputStream exportOssFile(String objectName) {
        // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
        OSSObject ossObject = ossClient.getObject(aliyunConfig.getBucketName(), objectName);
        // 读取文件内容。
        InputStream is = ossObject.getObjectContent();
//        if (is != null) {
//            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
//            while (true) {
//                String line = reader.readLine();
//                if (line == null) {
//                    break;
//                }
//                System.out.println("\n" + line);
//            }
//            // 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。
//            try {
//                is.close();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
            return is;
        }
}

  1. 控制层
package com.ycy.controller;

import com.aliyun.oss.model.OSSObjectSummary;
import com.ycy.service.FileUploadService;
import com.ycy.vo.FileUploadResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
 * @author gaojun
 * @desc
 * @email 15037584397@163.com
 */
@Controller
@RequestMapping("/oss")
@Api(value = "阿里云存储",tags = "阿里云存储")
public class FileUploadController {
    @Autowired
    private FileUploadService fileUploadService;
    /**
     * @author gaojun
     * @desc 文件上传到oss
     * @return FileUploadResult
     * @Param uploadFile
     */
    @ApiOperation(value = "上传文件",notes = "上传文件")
    @PostMapping("file/upload")
    @ResponseBody
    public FileUploadResult upload(@RequestParam("file") MultipartFile uploadFile) throws Exception {
        return this.fileUploadService.upload(uploadFile);
    }
    /**
     * @return FileUploadResult
     * @desc 根据文件名删除oss上的文件
     * http://localhost:8080/file/delete?fileName=images/2019/04/28/1556429167175766.jpg
     * @author gaojun
     * @Param objectName
     */
    @ApiOperation(value = "删除文件",notes = "删除文件")
    @PostMapping("file/delete")
    @ResponseBody
    public FileUploadResult delete(@RequestParam("fileName") String objectName)
            throws Exception {
        return this.fileUploadService.delete(objectName);
    }
    /**
     * @author gaojun
     * @desc 查询oss上的所有文件
     * http://localhost:8080/file/list
     * @return List<OSSObjectSummary>
     * @Param
     */
    @ApiOperation(value = "查看文件列表",notes = "查看文件列表")
    @PostMapping("file/list")
    @ResponseBody
    public List<OSSObjectSummary> list()
            throws Exception {
        return this.fileUploadService.list();
    }
    /**
     * @author gaojun
     * @desc 根据文件名下载oss上的文件
     * http://localhost:8080/file/delete
     * @return ResponseEntity<byte[]>
     * @Param objectName
     */
    @ApiOperation(value = "下载文件",notes = "下载文件")
    @PostMapping("file/download")
    @ResponseBody
    public ResponseEntity<byte[]> download(@RequestParam("fileName") String objectName) throws IOException {
        HttpHeaders headers = new HttpHeaders();
//         以流的形式下载文件,这样可以实现任意格式的文件下载
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//         文件名包含中文时乱码问题
//        headers.setContentDispositionFormData("attachment", new String(exportFile.getName().getBytes("utf-8"), "ISO8859-1"));
        headers.setContentDispositionFormData("attachment", objectName);
        InputStream is = this.fileUploadService.exportOssFile(objectName);
        return new ResponseEntity<byte[]>(is.toString().getBytes(),
                headers, HttpStatus.CREATED);
    }


    /**
     * @author gaojun
     * @desc 根据文件名下载oss上的文件
     * http://localhost:8080/file/delete
     * @return ResponseEntity<byte[]>
     * @Param objectName
     */
    @ApiOperation(value = "下载文件url",notes = "下载文件url")
    @PostMapping("file/exportFile")
    @ResponseBody
    public FileUploadResult exportFile(@RequestParam("fileName") String objectName) throws IOException {
        HttpHeaders headers = new HttpHeaders();
//         文件名包含中文时乱码问题
//        headers.setContentDispositionFormData("attachment", new String(exportFile.getName().getBytes("utf-8"), "ISO8859-1"));
        headers.setContentDispositionFormData("attachment", objectName);
        String url = this.fileUploadService.exportFile(objectName);
        return new FileUploadResult("121212",url,"done","success");
    }
}

这里插入了一个工具类,用于放回接口调用结果,很常用

package com.ycy.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author gaojun
 * @desc 用于前后端交互的返回值
 * @email 15037584397@163.com
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class FileUploadResult {
    // 文件唯一标识
    private String uid;
    // 文件名
    private String name;
    // 状态有:uploading done error removed
    private String status;
    // 服务端响应内容,如:'{"status": "success"}'
    private String response;
}

七 springboot 集成 nacos 配置 nacos 配置中心

nacos 本应该是springCloud中使用,这里再springboot项目中熟悉一下

  1. 下载nacos
    https://github.com/alibaba/nacos/releases
  2. 配置 nacos conf/application.properties 连接数据库 添加配置
# 数据源的数量。因为这里我们只配置一个数据源,所以设置为 1。
db.num=1
# 第 0 个数据源的配置
db.url.0=jdbc:mysql://localhost:3306/nacos_example?characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useCompression=true&useSSL=false&&allowMultiQueries=true&useUnicode=true&autoReconnect=true&serverTimezone=GMT%2B8
db.user=root
db.password=数据库密码
  1. 配置启动地址 默认 8848 ( 可以不配置)如果配置nacos集群时需要开启多个nacos服务,需要配置不同启动地址,server.port属性设置nacos服务的启动端口
    在这里插入图片描述
  2. 执行数据库脚本
    在这里插入图片描述
  3. 启动nacos startup.cmd 文件默认开启集群服务 ,可以设置之开启单个服务
    在这里插入图片描述
    startup.cmd 文件 MODE属性 standalone 只开启单个服务,cluster 开启集群服务
    在这里插入图片描述
  4. 配置 nacos 集群 (这里不需要配置,只需要知道就好)。
    如果需要配置nacos集群,首先复制多个 nacos 文件 比如 nacos-01 nacos-02 ,然后将每个nacos文件中的 conf/ cluster.conf.example文件重命名为 cluster.conf .并编辑输入
10.0.110.150:8848
10.0.110.150:8858
10.0.110.150:8868

这三个地址分别是 nacos nacos-01 nacos-02 启动文件的启动地址,格式是 ip:port ,这里最好使用正式的IP地址,不要使用 127.0.0.1
开启集群时,设置 startup.com MODE属性为 cluster,然后启动nacos nacos-01 nacos-02即可。

  1. 启动nacos后 代码中引入依赖 这里使用的是 nacos-springboot 的依赖 ,如果使用 springbootCloud 需要使用 第二个依赖
        <!-- 实现对 Nacos 作为配置中心的自动化配置 -->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>nacos-config-spring-boot-starter</artifactId>
            <version>0.2.4</version>
        </dependency>
        <!--        <dependency>-->
<!--            <groupId>com.alibaba.cloud</groupId>-->
<!--            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>-->
<!--            <version>2021.0.1.0</version>-->
<!--        </dependency>-->
  1. 配置文件配置 nacos
nacos:
  # Nacos 配置中心的配置项,对应 NacosConfigProperties 配置类
  config:
    server-addr: 127.0.0.1:8848 # Nacos 服务器地址
    bootstrap:
      enable: true # 是否开启 Nacos 配置预加载功能。默认为 false。
      log-enable: true # 是否开启 Nacos 支持日志级别的加载时机。默认为 false。
    data-id: example # 使用的 Nacos 配置集的 dataId。
    type: YAML # 使用的 Nacos 配置集的配置格式。默认为 PROPERTIES。
    group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP。
    namespace:  # 使用的 Nacos 的命名空间,默认为 null。
    auto-refresh: true # 是否自动刷新,默认为 false。
  1. 创建配置类 OrderPropertiesConfig
package com.ycy.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @author: luck
 * @date: 2023/12/13 10:36
 * @Description:
 */

@Component
@ConfigurationProperties(prefix = "order")
@Data
public class OrderPropertiesConfig {
    // id;
    private Integer id;
    // 年龄
    private Integer age;
}
  1. 启动类增加方法
package com.ycy;

import com.ycy.config.OrderPropertiesConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import tk.mybatis.spring.annotation.MapperScan;



@SpringBootApplication
@EnableSwagger2
@MapperScan("com.ycy.mapper")
public class SwaggerApplication {
    public static void main(String[] args) {
        SpringApplication.run(SwaggerApplication.class, args);
    }

    @Component
    public class OrderPropertiesCommandLineRunner implements CommandLineRunner {
        private final Logger logger = LoggerFactory.getLogger(getClass());
        @Autowired
        private OrderPropertiesConfig orderProperties;
        @Override
        public void run(String... args) {
            logger.info("id:" + orderProperties.getId());
            logger.info("age:" + orderProperties.getAge());
        }

    }

    @Component
    public class ValueCommandLineRunner implements CommandLineRunner {
        private final Logger logger = LoggerFactory.getLogger(getClass());
        //        @NacosValue(value = "${order.pay-timeout-seconds}")
        @Value(value = "${order.id}")
        private Integer id;
        //        @NacosValue(value = "${order.create-frequency-seconds}")
        @Value(value = "${order.age}")
        private Integer age;
        @Override
        public void run(String... args) {
            logger.info("id:" + id);
            logger.info("age:" + age);
        }
    }
}
  1. 启动 nacos 后 登录 127.0.0.1:8848/nacos/index.html 增加配置
    在这里插入图片描述
    在这里插入图片描述
    12 启动项目 查看日志
    在这里插入图片描述

八 配置nacos 注册中心

  1. 导入依赖
        <!-- 实现对 Nacos 作为注册中心的自动化配置 -->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>nacos-discovery-spring-boot-starter</artifactId>
            <version>0.2.4</version>
        </dependency>
  1. 添加配置 这里需要配置 springboto 服务名称 以及nacos配置

spring:
  application:
    name: springboot-application # 应用名
 
 nacos: 
  discovery:
   server-addr: 127.0.0.1:8848 # Nacos 服务器地址
   auto-register: true # 是否自动注册到 Nacos 中。默认为 false。
   namespace: # 使用的 Nacos 的命名空间,默认为 null。
   register:
    service-name: ${spring.application.name} # 注册到 Nacos 的服务名
    group-name: DEFAULT_GROUP # 使用的 Nacos 服务分组,默认为 DEFAULT_GROUP。
    cluster-name: # 集群名,默认为空。
  1. 创建 服务提供者控制类
package com.ycy.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/provider")
public class ProviderController {

    @GetMapping("/demo")
    public String provider() {
        return "echo";
    }

}
  1. 创建 服务消费者 控制类
package com.ycy.controller;

import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@RestController
@RequestMapping("/consumer")
public class ConsumerController {

    @NacosInjected
    private NamingService namingService;

    private RestTemplate restTemplate = new RestTemplate();

    @GetMapping("/demo")
    public String consumer() throws IllegalStateException, NacosException {
        // <1> 获得实例
        Instance instance = null;
        if (false) {
            List<Instance> instances = namingService.getAllInstances("springboot-application");
            // 获得首个实例,进行调用
            instance = instances.stream().findFirst()
                    .orElseThrow(() -> new IllegalStateException("未找到对应的 Instance"));
        } else {
            instance = namingService.selectOneHealthyInstance("springboot-application");
        }
        // <2> 执行请求
        return restTemplate.getForObject("http://" + instance.toInetAddr() + "/provider/demo",
                String.class);
    }

}
  1. 效果
    在这里插入图片描述

在这里插入图片描述

总结

提示:这里对文章进行总结:

例如:以上就是今天要 讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值