Introduction to AOP

The basic concept of AOP

AOP (Aspect Oriented Programming) is a technology of aspect-oriented programming that realizes the unified maintenance of program functions through pre-compilation and dynamic agents during runtime. AOP is a continuation of OOP, a hot spot in software development, and an important content in the Spring framework.

The role of AOP

The core function of AOP is to enhance the function of the program without modifying the code during the running of the program. Make the indispensable public functions into aspects, and cut into the code to run as the program runs. When writing a business, only focus on core functions, and no longer consider public functions such as transactions and logs, which reduces the burden of coding and focuses more on business

AOP terminology

1. Aspect

Which methods are intercepted and what to do after interception, these concerns are called aspects

2, the connection point (joinpoint)

The intercepted point, because Spring only supports method type connection points, so the connection point in Spring refers to the intercepted method. In fact, the connection point can also be a field or a constructor.

3. Pointcut

Definition of interception of connection points

4. Advice

The so-called notification refers to the code to be executed after intercepting the connection point. The notification is divided into five categories: pre, post, exception, final, and surround notification

5. Target

The target object of the proxy, the process of applying the aspect to the target object and causing the creation of the proxy object

6. Introduction\Weave (introduction, weave)

Under the premise of not modifying the code, the introduction can dynamically add some methods or fields to the class at runtime

AOP configuration steps

1. Import dependencies

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.2.8.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.9.5</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.5</version>
        </dependency>

2. Write notification class

/**
 * 日志输出通知类
 */
public class LogAdvise {
    
    

    public void beforeLog(){
    
    
        System.out.println("方法开始执行!");
    }

    public void afterLog(){
    
    
        System.out.println("方法后置执行!");
    }

    public void afterReturning(){
    
    
        System.out.println("方法返回了数据");
    }

    public void afterThrowing(){
    
    
        System.out.println("方法抛出了异常");
    }

    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
    
    
        System.out.println("around方法名:" + joinPoint.getSignature().getName());
        System.out.println("around --前置");
        //原来方法
        joinPoint.proceed();
        System.out.println("around --后置");
    }
}

3. AOP configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--配置包的扫描-->
    <context:component-scan base-package="com.blb.aop_demo"></context:component-scan>
    <!--配置通知类-->
    <bean id="logAdvise" class="com.blb.aop_demo.util.LogAdvise"></bean>
    <!--配置切面-->
    <aop:config>
        <!--配置切入点-->
        <aop:pointcut id="pc" expression="execution(* com.blb.aop_demo.service.*Service.*(..))"/>
        <!--配置切面 ref是通知类的bean-->
        <aop:aspect id="aspect1" ref="logAdvise">
            <!--前置通知 method是对应的通知方法 pointcut-ref是切入点-->
            <aop:before method="beforeLog" pointcut-ref="pc"></aop:before>
            <!--后置-->
            <aop:after method="afterLog" pointcut-ref="pc"></aop:after>
            <!--后置返回-->
            <aop:after-returning method="afterReturning" pointcut-ref="pc"></aop:after-returning>
            <!--后置抛异常-->
            <aop:after-throwing method="afterThrowing" pointcut-ref="pc"></aop:after-throwing>
            <!--环绕-->
            <aop:around method="around" pointcut-ref="pc"></aop:around>
        </aop:aspect>
    </aop:config>
</beans>

AOP's related solution

@Aspect aspect, configured to the aspect class

@PointCut("Expression") Configure the entry point and add it to the method

@Before Configure the pre-notification method

@After configure the post notification method

@Around Configure surround notification method

@AfterReturning Configure the post return value notification method

@AfterThrowing configures the post-throwing exception notification method

AOP annotation configuration

1. Configuration class

@ComponentScan(basePackages = "com.blb.aop_demo")
@Configuration
//启动AspectJ的注解配置
@EnableAspectJAutoProxy
public class AopConfig {
    
    
}

2. Log section

/**
 * 日志切面
 */
@Aspect
@Component
public class LogAspect {
    
    

    //配置切入点
    @Pointcut("execution(* com.blb.aop_demo.service.*Service.*(..))")
    public void pointcut(){
    
    
    }

    //配置通知方法
    @Before("pointcut()")
    public void beforeLog(){
    
    
        System.out.println("这是前置的通知方法!!");
    }
}

3. Test

AnnotationConfigApplicationContext context2 = new   
                              AnnotationConfigApplicationContext(AopConfig.class);
GoodsService goodsService = context2.getBean(GoodsService.class);
goodsService.queryGoods();

Use AOP to implement log tracking

1. Import log4j dependency.
Supplement: Quick import depends on
Alt+insert key

Insert a picture description here
Insert picture description here
Insert picture description here
. The dependency is imported for the first time, and it is red. After loading, it will be fine.

2. Add log4j.properties

# ROOTER
log4j.rootLogger=DEBUG,CONSOLE,FILE

# CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%-d{
    
    yyyy-MM-dd HH\:mm\:ss} %-5p %-20c %x %m%n

# FILE
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.File=logs.log
log4j.appender.FILE.MaxBackupIndex=20
log4j.appender.FILE.MaxFileSize=10MB
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%-d{
    
    yyyy-MM-dd HH\:mm\:ss} %-5p %-20c %x %m%n

# ERROR
log4j.appender.ERR = org.apache.log4j.DailyRollingFileAppender
log4j.appender.ERR.File =error.log
log4j.appender.ERR.Append = true
log4j.appender.ERR.Threshold = ERROR
log4j.appender.file.DatePattern='.'yyyy-MM-dd'.log'
log4j.appender.ERR.layout = org.apache.log4j.PatternLayout
log4j.appender.ERR.layout.ConversionPattern = %-d{
    
    yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

3. Compile log aspects

/**
 * Log4j日志输出切面
 */
@Aspect
@Component
public class Log4jAspect {
    
    

    //创建日志对象
    private Logger logger = Logger.getLogger(Log4jAspect.class);

    //给所有的service类的所有方法加日志跟踪
    @Pointcut("execution(* com.blb.aop_demo.service.*Service.*(..))")
    public void logPointcut(){
    
    
    }

    //配置环绕通知
    @Around("logPointcut()")
    public Object aroundLog(ProceedingJoinPoint point) throws Throwable {
    
    
        //记录方法执行前时间
        long start = System.currentTimeMillis();
        //打印方法名称
        if(logger.isDebugEnabled()){
    
    
            logger.debug("当前执行方法:" + point.getSignature().getName());
        }
        //打印参数
        Object[] args = point.getArgs();
        for(Object arg : args){
    
    
            if(logger.isDebugEnabled()){
    
    
                logger.debug("参数:"+arg);
            }
        }
        //打印返回值
        Object result = point.proceed();
        if(logger.isDebugEnabled()){
    
    
            logger.debug("方法返回值:" +result);
        }
        //打印执行时间
        long end = System.currentTimeMillis();
        if(logger.isDebugEnabled()){
    
    
            logger.debug("方法执行时间:" +(end - start));
        }
        return result;
    }
}

Guess you like

Origin blog.csdn.net/weixin_44889894/article/details/115056387
AOP