SpringAOP & Mybatis-plus & SpringBoot 整合
依赖
< dependency>
< groupId> com.fasterxml.jackson.core</ groupId>
< artifactId> jackson-databind</ artifactId>
< version> 2.11.4</ version>
</ dependency>
< dependency>
< groupId> org.aspectj</ groupId>
< artifactId> aspectjrt</ artifactId>
< scope> runtime</ scope>
</ dependency>
< dependency>
< groupId> org.aspectj</ groupId>
< artifactId> aspectjweaver</ artifactId>
</ dependency>
< dependency>
< groupId> eu.bitwalker</ groupId>
< artifactId> UserAgentUtils</ artifactId>
< version> ${user.agent.version}</ version>
</ dependency>
< dependency>
< groupId> cn.hutool</ groupId>
< artifactId> hutool-all</ artifactId>
< version> ${hutool.version}</ version>
</ dependency>
< dependency>
< groupId> com.google.guava</ groupId>
< artifactId> guava</ artifactId>
< version> ${guava.version}</ version>
</ dependency>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-web</ artifactId>
</ dependency>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-test</ artifactId>
< scope> test</ scope>
</ dependency>
< dependency>
< groupId> org.projectlombok</ groupId>
< artifactId> lombok</ artifactId>
</ dependency>
< dependency>
< groupId> mysql</ groupId>
< artifactId> mysql-connector-java</ artifactId>
</ dependency>
< dependency>
< groupId> com.baomidou</ groupId>
< artifactId> mybatis-plus-boot-starter</ artifactId>
< version> 3.0.5</ version>
</ dependency>
aspectj 文件夹
@Aspect
@Component
@Slf4j
public class AopLog {
@Autowired
private LogUserMapper logUserMapper;
private static final ThreadLocal < Date > DATE_THREAD_LOCAL = new ThreadLocal < > ( ) ;
@Pointcut ( "execution(public * com.demo.controller.*Controller.*(..))" )
public void log ( ) {
}
@Around ( "log()" )
public Object aroundLog ( ProceedingJoinPoint point) throws Throwable {
DATE_THREAD_LOCAL. set ( new Date ( ) ) ;
ServletRequestAttributes attributes = ( ServletRequestAttributes ) RequestContextHolder . getRequestAttributes ( ) ;
HttpServletRequest request = Objects . requireNonNull ( attributes) . getRequest ( ) ;
long startTime = System . currentTimeMillis ( ) ;
Object result = point. proceed ( ) ;
String header = request. getHeader ( "User-Agent" ) ;
UserAgent userAgent = UserAgent . parseUserAgentString ( header) ;
final LogUser l = LogUser . builder ( )
. threadId ( Long . toString ( Thread . currentThread ( ) . getId ( ) ) )
. threadName ( Thread . currentThread ( ) . getName ( ) )
. ip ( getIp ( request) )
. url ( request. getRequestURL ( ) . toString ( ) )
. beginTime ( DATE_THREAD_LOCAL. get ( ) )
. endTime ( new Date ( ) )
. classMethod ( String . format ( "%s.%s" , point. getSignature ( ) . getDeclaringTypeName ( ) ,
point. getSignature ( ) . getName ( ) ) )
. httpMethod ( request. getMethod ( ) )
. requestParams ( new ObjectMapper ( ) . writeValueAsString ( getNameAndValue ( point) ) )
. result ( new ObjectMapper ( ) . writeValueAsString ( result) )
. timeCost ( System . currentTimeMillis ( ) - startTime)
. userAgent ( header)
. browser ( userAgent. getBrowser ( ) . toString ( ) )
. os ( userAgent. getOperatingSystem ( ) . toString ( ) ) . build ( ) ;
addUser ( l) ;
log. info ( "0-----------------------0" , DATE_THREAD_LOCAL. get ( ) ) ;
log. info ( "Request LogUser Info : {}" , JSONUtil . toJsonStr ( l) ) ;
return result;
}
@Transactional ( value = "Exception.class" )
void addUser ( LogUser logUser) {
logUserMapper. insert ( logUser) ;
}
private Map < String , Object > getNameAndValue ( ProceedingJoinPoint joinPoint) {
final Signature signature = joinPoint. getSignature ( ) ;
MethodSignature methodSignature = ( MethodSignature ) signature;
final String [ ] names = methodSignature. getParameterNames ( ) ;
final Object [ ] args = joinPoint. getArgs ( ) ;
if ( ArrayUtil . isEmpty ( names) || ArrayUtil . isEmpty ( args) ) {
return Collections . emptyMap ( ) ;
}
if ( names. length != args. length) {
log. warn ( "{}方法参数名和参数值数量不一致" , methodSignature. getName ( ) ) ;
return Collections . emptyMap ( ) ;
}
Map < String , Object > map = Maps . newHashMap ( ) ;
for ( int i = 0 ; i < names. length; i++ ) {
map. put ( names[ i] , args[ i] ) ;
}
return map;
}
private static final String UNKNOWN = "unknown" ;
public static String getIp ( HttpServletRequest request) {
String ip = request. getHeader ( "x-forwarded-for" ) ;
if ( ip == null || ip. length ( ) == 0 || UNKNOWN. equalsIgnoreCase ( ip) ) {
ip = request. getHeader ( "Proxy-Client-IP" ) ;
}
if ( ip == null || ip. length ( ) == 0 || UNKNOWN. equalsIgnoreCase ( ip) ) {
ip = request. getHeader ( "WL-Proxy-Client-IP" ) ;
}
if ( ip == null || ip. length ( ) == 0 || UNKNOWN. equalsIgnoreCase ( ip) ) {
ip = request. getRemoteAddr ( ) ;
}
String comma = "," ;
String localhost = "127.0.0.1" ;
if ( ip. contains ( comma) ) {
ip = ip. split ( "," ) [ 0 ] ;
}
if ( localhost. equals ( ip) ) {
try {
ip = InetAddress . getLocalHost ( ) . getHostAddress ( ) ;
} catch ( UnknownHostException e) {
log. error ( e. getMessage ( ) , e) ;
}
}
return ip;
}
}
pojo 文件夹
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName ( value = "logUser" )
public class LogUser implements Serializable {
private String threadId;
private String threadName;
private String ip;
private String url;
private String httpMethod;
private String classMethod;
private String requestParams;
private String result;
private Long timeCost;
private String os;
private String browser;
private String userAgent;
private Date beginTime;
private Date endTime;
}
controller文件夹
@Slf4j
@RestController
public class TestController {
@GetMapping ( "/demo" )
public String testDemo ( ) {
return "demo" ;
}
@GetMapping ( "/test" )
public Dict test ( String who) {
return Dict . create ( ) . set ( "who" , StrUtil . isBlank ( who) ? "URL" : who) ;
}
@PostMapping ( "/testJson" )
public Dict testJson ( @RequestBody Map < String , Object > map) {
final String jsonStr = JSONUtil . toJsonStr ( map) ;
log. info ( jsonStr) ;
return Dict . create ( ) . set ( "json" , map) ;
}
}
测试结果
测试一
测试二
点点关注