Tip: there is the source code address below, please take it yourself
preface
Do you still get the log object directly in the class and call the method to print the log? How to implement a logging feature elegantly using AOP+ custom annotations
Tip: The following is the main content of this article, the case is for reference only
I. Technical introduction
What is AOP?
In the software industry, AOP for the abbreviation of Aspect Oriented Programming, meaning: section-oriented Programming, through pre-compilation and runtime dynamic proxy to achieve unified maintenance of program functions of a technology. AOP is a continuation of OOP, a hot topic in software development, and an important content in Spring framework. It is a derivative paradigm of functional programming. Using AOP, each part of the business logic can be isolated, thus reducing the degree of coupling between each part of the business logic, improving the reusability of the program, and improving the efficiency of development. — from Baidu Baike
Two, start to use
1. Code directory structure
2. Start coding
POM.xml
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> </dependencies>Copy the code
Let’s use SpringBoot to write an on demand annotation, write an on demand annotation
package com.hyh.log.annotation;
import com.hyh.log.config.HyhLogAutoConfiguration;
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
/** * Enable log annotation **@Author: heyuhua
* @Date: 2021/1/28 who neglects * /
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import({HyhLogAutoConfiguration.class})
public @interface EnableHyhLog {
}
Copy the code
Auto-configuration class
package com.hyh.log.config;
import com.hyh.log.aspect.LogAspect;
import com.hyh.log.service.LogService;
import com.hyh.log.service.impl.LogServiceImpl;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Log AutoConfiguration
*
* @Author: heyuhua
* @Date: 2021/1/28 16:02 * /
@ConditionalOnWebApplication
@Configuration(proxyBeanMethods = false)
public class HyhLogAutoConfiguration {
@Bean
public LogAspect logAspect(a) {
return new LogAspect();
}
@Bean
public LogService logService(a) {
return newLogServiceImpl(); }}Copy the code
Custom log annotations
package com.hyh.log.annotation;
import java.lang.annotation.*;
/** ** *@Author: heyuhua
* @Date: 2021/1/28 16:02 * /
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface HyhLog {
/** * description **@return* /
String value(a) default "";
}
Copy the code
Log section code
package com.hyh.log.aspect;
import com.hyh.log.annotation.HyhLog;
import com.hyh.log.service.LogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import javax.annotation.Resource;
/**
* Log Aspect
*
* @Author: heyuhua
* @Date: 2021/1/28 16:02 * /
@Aspect
public class LogAspect {
/** * Log service */
@Resource
private LogService logService;
/** * surround operation **@param point
* @param hyhLog
* @return
* @throws Throwable
*/
@Around("@annotation(hyhLog)")
public Object around(ProceedingJoinPoint point, HyhLog hyhLog) throws Throwable {
String className = point.getTarget().getClass().getName();
String methodName = point.getSignature().getName();
logService.info([class] :{}, [method] :{}", className, methodName);
Object obj = point.proceed();
// do something
return obj;
}
/** ** ** *@param point
* @param hyhLog
* @return
* @throws Throwable
*/
@Before("@annotation(hyhLog)")
public void before(JoinPoint point, HyhLog hyhLog) throws Throwable {
logService.info("Perform the front operation..." + hyhLog.value());
// do something
}
/** ** after operation **@param point
* @param hyhLog
* @return
* @throws Throwable
*/
@After("@annotation(hyhLog)")
public void after(JoinPoint point, HyhLog hyhLog) throws Throwable {
logService.info("Perform post-operation..." + hyhLog.value());
// do something}}Copy the code
Log Service Interface
package com.hyh.log.service;
/** * Log interface **@Author: heyuhua
* @Date: 2021/1/28 and * /
public interface LogService {
/**
* info
*
* @param msg
*/
void info(String msg);
/**
* info
*
* @param msg
* @param o
*/
void info(String msg, Object o);
/**
* info
*
* @param msg
* @param throwable
*/
void info(String msg, Throwable throwable);
/**
* info
*
* @param msg
* @param o
*/
void info(String msg, Object... o);
/**
* info
*
* @param msg
* @param o
* @param throwable
*/
void info(String msg, Object o, Throwable throwable);
/**
* error
*
* @param msg
*/
void error(String msg);
/**
* error
*
* @param msg
* @param o
*/
void error(String msg, Object o);
/**
* error
*
* @param msg
* @param throwable
*/
void error(String msg, Throwable throwable);
/**
* error
*
* @param msg
* @param o
* @param throwable
*/
void error(String msg, Object o, Throwable throwable);
}
Copy the code
Log service interface implementation
package com.hyh.log.service.impl;
import com.hyh.log.service.LogService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
/** * log service interface implementation **@Author: heyuhua
* @Date: 2021/1/28 17:04 * /
@Service
public class LogServiceImpl implements LogService {
/** * log */
private static final Logger LOGGER = LoggerFactory.getLogger(LogServiceImpl.class);
@Override
public void info(String msg) {
LOGGER.info(msg);
}
@Override
public void info(String msg, Object o) {
LOGGER.info(msg, o);
}
@Override
public void info(String msg, Throwable throwable) {
LOGGER.info(msg, throwable);
}
@Override
public void info(String msg, Object... o) {
LOGGER.info(msg, o);
}
@Override
public void info(String msg, Object o, Throwable throwable) {
LOGGER.info(msg, o, throwable);
}
@Override
public void error(String msg) {
LOGGER.error(msg);
}
@Override
public void error(String msg, Object o) {
LOGGER.error(msg, o);
}
@Override
public void error(String msg, Throwable throwable) {
LOGGER.error(msg, throwable);
}
@Override
public void error(String msg, Object o, Throwable throwable) { LOGGER.error(msg, o, throwable); }}Copy the code
Unit testing
OK, no nonsense, let’s go to the unit test and start using our annotations in the SpringBoot projectIf you look in the red box, we write an on-demand import annotation, and then the Controller layer writes an interface that uses HyhLog annotations
@HyhLog(value = "hello world test")
@RequestMapping(value = "hello", method = RequestMethod.GET)
public String hello(a) {
return "hello";
}
Copy the code
Visit the Hello interface to see the result
conclusion
AOP can implement many functions based on dynamic proxy, such as permission control, logging, transaction commit and rollback, etc. a series of operations, through non-invasive way to achieve business decoupling, function enhancement, let us use the most elegant code to achieve the most complex functions.
The author remarks
I see a long way to go, I’m willing to work with you. Thank you very much for your likes, favorites and comments. See you next time.
Source code: click here to view the source code.