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.*; ** @author: heyuhua * @date: 2021/1/28 15:32 */ @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() { return new LogAspect(); } @Bean public LogService logService() { return new LogServiceImpl(); }}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() default ""; } Duplicate codeCopy 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 {/** * 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; } /** * Pre-operation ** @param point * @param hyhLog * @return * @throws Throwable */ @before ("@annotation(hyhLog)") public Void before(JoinPoint Point, HyhLog HyhLog) throws Throwable {logService.info(" Perform the preceding operation..." + hyhLog.value()); // do something} /** * Post-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 codeCopy the code
Log Service Interface
package com.hyh.log.service; /** * @author: heyuhua * @date: 2021/1/28 15:37 */ 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); } Duplicate codeCopy 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; ** @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 codeCopy the code
Unit testing
OK, no nonsense, let’s go to the unit test and start using our annotations in the SpringBoot project
If 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() {
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.
Source: www.tuicool.com/articles/FF…