类图
包结构
代码实例
-
pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.22.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>xxjob-actouor</artifactId> <version>0.0.1-SNAPSHOT</version> <name>xxjob-actouor</name> <description>xxjob-actouor</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> <version>1.5.22.RELEASE</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <releases> <enabled>false</enabled> </releases> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> <pluginRepository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <releases> <enabled>false</enabled> </releases> </pluginRepository> </pluginRepositories> </project>
-
yml
server.port=9000 # 控制是否打印日志 false 不打印日志 true 打印日志 health.flag=true # 日志策类配置 default 默认日志类 caChe 添加缓存的日志类 health.strategy=default # 健康检查结果缓存超时时间,只有 health.strategy=caChe 这项配置才有意义 health.timeOut=10
-
code
-
Strategy
HealthLogsSuper
package com.example.xxjobactouor.Strategy; import org.aspectj.lang.ProceedingJoinPoint; /** * @Description 健康检查日志策略父类 * @ClassName HealthSuper * @Author 康世行 * @Date 21:23 2023/6/7 * @Version 1.0 **/ public abstract class HealthLogsSuper { //获取健康检查结果 public abstract Object getHealthLogs( ProceedingJoinPoint joinPoint ); }
DefaultHealthLogs
package com.example.xxjobactouor.Strategy; import com.example.xxjobactouor.Strategy.common.HealthCommonPrint; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * @Description 默认日志策略-控制日志是否打印 * @ClassName DefaultHealth * @Author 康世行 * @Date 21:34 2023/6/7 * @Version 1.0 **/ @Service @Slf4j public class DefaultHealthLogs extends HealthLogsSuper { @Autowired private HealthCommonPrint healthPrintLogs; @Override public Object getHealthLogs(ProceedingJoinPoint joinPoint) { Object proceed=null; //目标类 Object target = joinPoint.getTarget(); //接口请求开始时间 long start=System.currentTimeMillis(); try { //进入类之前打印日志 healthPrintLogs.printPreHealthLogs(target); proceed=joinPoint.proceed(); //进入类之后的日志 healthPrintLogs.printAftHealthLogs(target,start); } catch (Throwable e) { throw new RuntimeException(e); } return proceed; } }
CacheHealthLogs
package com.example.xxjobactouor.Strategy; import com.example.xxjobactouor.Strategy.common.CacheHealth; import com.example.xxjobactouor.Strategy.common.HealthCommonPrint; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.util.concurrent.TimeUnit; /** * @Description 对结果进行缓存的日志策略 * @ClassName LogsAndCacheHealth * @Author 康世行 * @Date 21:38 2023/6/7 * @Version 1.0 **/ @Service @Slf4j public class CacheHealthLogs extends HealthLogsSuper { @Autowired private CacheHealth cacheHealth; @Value("${health.timeOut:5}") private long timeOut; //缓存key private final static String cacheKey="healthInfo"; //打印日志 @Autowired private HealthCommonPrint healthPrintLogs; @Override public Object getHealthLogs(ProceedingJoinPoint joinPoint) { Object proceed=null; //目标类 Object target = joinPoint.getTarget(); //接口请求开始时间 long start=System.currentTimeMillis(); try { //进入类之前打印日志 healthPrintLogs.printPreHealthLogs(target); //从缓存获取健康检查信息 proceed= cacheHealth.get(cacheKey); if (proceed==null){ //再次获取健康检查的信息并保存到缓存,用于下次使用提高接口查询效率 proceed=joinPoint.proceed(); cacheHealth.put(cacheKey,proceed,timeOut, TimeUnit.SECONDS); } //进入类之后的日志 healthPrintLogs.printAftHealthLogs(target,start); } catch (Throwable e) { throw new RuntimeException(e); } return proceed; } }
HealthLogsContext
package com.example.xxjobactouor.Strategy; import org.aspectj.lang.ProceedingJoinPoint; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * @Description * 健康检查日志策略上下文类-用于维护 具体使用的那个策略对象 结合简单工厂使用 * @ClassName HealthLogsContext * @Author 康世行 * @Date 21:46 2023/6/7 * @Version 1.0 **/ @Service public class HealthLogsContext { HealthLogsSuper logsSuper; @Autowired private DefaultHealthLogs defaultHealthLogs; @Autowired private CacheHealthLogs cacheHealthlogs; //设置具体策略 public void setStrategy(String strategy){ switch (strategy){ case "default": logsSuper=defaultHealthLogs; break; case "caChe": logsSuper=cacheHealthlogs; break; } } //执行具体策略 public Object getResult(ProceedingJoinPoint joinPoint ){ Object healthLogs = logsSuper.getHealthLogs(joinPoint); return healthLogs; } }
HealthLogs
package com.example.xxjobactouor; import com.example.xxjobactouor.Strategy.HealthLogsContext; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.stereotype.Component; import java.util.concurrent.TimeUnit; /** * @Description 记录监控检查-日志 * @ClassName HealthLogs * @Author 康世行 * @Date 20:15 2023/6/7 * @Version 1.0 **/ @Aspect @Component @Slf4j public class HealthLogs { @Pointcut("execution(public * com.example.xxjobactouor.Healthimpl.health())") public void logs(){}; @Autowired private HealthLogsContext context; @Value("${health.strategy:default}") private String strategy; @Around("logs()") public Object log(ProceedingJoinPoint joinPoint){ Object proceed=null; //设置使用那个日志策略 context.setStrategy(strategy); // 获取健康检查返回值 proceed= context.getResult(joinPoint); return proceed; } }
-
common
CacheHealth
package com.example.xxjobactouor.Strategy.common; import org.springframework.stereotype.Component; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * @Description TODO * @ClassName CacheHealth * @Author 康世行 * @Date 20:50 2023/6/7 * @Version 1.0 **/ @Component public class CacheHealth { private final Map<String,Object> cacheHealth=new ConcurrentHashMap<>(); public void put(String key, Object value, long ttl, TimeUnit timeUnit) { cacheHealth.put(key, value); Executors.newSingleThreadScheduledExecutor().schedule(() -> cacheHealth.remove(key,value), ttl, timeUnit); } public Object get(String key) { return cacheHealth.get(key); } }
HealthCommonPrint
package com.example.xxjobactouor.Strategy.common; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; /** * @Description 日志打印类-所有日志策略公共类 * @ClassName HealthPrintLogs * @Author 康世行 * @Date 22:30 2023/6/7 * @Version 1.0 **/ @Service @Slf4j public class HealthCommonPrint { @Value("${health.flag:false}") private boolean flag; //打印执行前健康检查日志 public void printPreHealthLogs(Object joinPoint) { if (flag){ log.info("进入"+joinPoint.getClass().getName()+"类之前"); } } //打印执行后健康检查日志 public void printAftHealthLogs(Object joinPoint,long start) { if (flag){ log.info("进入"+joinPoint.getClass().getName()+"类之后"); } if (flag){ long end=System.currentTimeMillis()-start; log.info("耗时"+end); } } }
-