springboot 集成 mybats swagger redis pageHelper nacos backlog…
redis 序列化 fastjson序列化漏洞 根据包名序列化 ,反序列化时包路径不同容易引起报错
spring aop ioc
springboot 自动装配 自定义配置
springboot …
文章目录
前言
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
一、创建sprngboot项目 集成 mybatis
- 导入依赖 常用依赖
<!-- 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>
- 导入m ybatis 依赖
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
- 链接数据库 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> {
}
- 编写实体类
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;
}
- 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);
}
- 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);
}
- 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);
}
}
- 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
- 导入依赖
<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>
- 创建配置文件 配置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()
);
}
}
- 启动项添加 使用注解
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 分页
- 导入依赖
<!-- pageHelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.6</version>
</dependency>
- 创建 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;
}
}
- 在 查找数据时使用 ,比如在 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);
}
}
- 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);
}
}
- 结果
四 配置durld 数据库连接池
- 添加依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.18</version>
</dependency>
- 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
- 项目启动时显示
- 配置 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 配置
- 本地下载 redis
- 导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.1.7.RELEASE</version>
</dependency>
- 配置 redis
spring:
redis:
host: 127.0.0.1
port: 6379
- 使用
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();
}
}
- 结果
六 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
- 前提条件 拥有阿里云存储服务 使用阿里云账号创建ducket,并配置 AccessKey
[阿里云服务]https://www.aliyun.com/?spm=a2c4g.750001.J_4VYgf18xNlTAyFFbOuOQe.2.5f705155Di1lWx - 导入依赖
<!-- 阿里云 存储 -->
<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>
- 配置 阿里云连接 创造 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
- 创建配置文件 生成 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);
}
}
- 定义文件上传、下载等接口
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);
}
- 实现类
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;
}
}
- 控制层
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项目中熟悉一下
- 下载nacos
https://github.com/alibaba/nacos/releases - 配置 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=数据库密码
- 配置启动地址 默认 8848 ( 可以不配置)如果配置nacos集群时需要开启多个nacos服务,需要配置不同启动地址,server.port属性设置nacos服务的启动端口
- 执行数据库脚本
- 启动nacos startup.cmd 文件默认开启集群服务 ,可以设置之开启单个服务
startup.cmd 文件 MODE属性 standalone 只开启单个服务,cluster 开启集群服务
- 配置 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即可。
- 启动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>-->
- 配置文件配置 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。
- 创建配置类 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;
}
- 启动类增加方法
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);
}
}
}
- 启动 nacos 后 登录 127.0.0.1:8848/nacos/index.html 增加配置
12 启动项目 查看日志
八 配置nacos 注册中心
- 导入依赖
<!-- 实现对 Nacos 作为注册中心的自动化配置 -->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-discovery-spring-boot-starter</artifactId>
<version>0.2.4</version>
</dependency>
- 添加配置 这里需要配置 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: # 集群名,默认为空。
- 创建 服务提供者控制类
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";
}
}
- 创建 服务消费者 控制类
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);
}
}
- 效果
总结
提示:这里对文章进行总结:
例如:以上就是今天要 讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。