基于注解方式的Spring AOP

1、基于注解实现AOP

@Aspect : 指定切面类
通知方法:

  • 前置通知(@Before)
  • 后置通知(@After)
  • 返回通知 (@AfterReturning)
  • 异常通知 (@AfterThrowing)
  • 环绕通知 (@Around)

@PointCut:公共切入点表达式
@EnableAspectJAutoProxy : 开启基于注解的AOP模式

2、基于注解实现AOP案例

2.1 pom.xml

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.lrm</groupId>
    <artifactId>Spring_4</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.9</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjtools</artifactId>
            <version>1.8.9</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2.2 通知类

package com.lrm;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author RuiMing Lin
 * @date 2020-04-14 15:54
 */
@Component
@Aspect
public class Logger {
    
    

    @Pointcut("execution(* com.lrm.service.*.*(..))")
    private void pointcut(){
    
    }

    /**
     * 记录日志的方法
     *
     * @param methodName
     * @param flag
     * @param time
     * @throws IOException
     */
    private void log(String methodName, String flag, String time) throws IOException {
    
    
        File file = new File("log.txt");
        if (!file.exists()) {
    
    
            file.createNewFile();
        }
        try (FileWriter fw = new FileWriter("log.txt", true);) {
    
    
            fw.write(new String(time + methodName + flag) + '\n');
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

    /**
     * 前置通知
     */
//    @Before(value = "execution(* com.lrm.service.*.*(..))")   // 第一种方式,直接输入切入点表达式
    @Before("pointcut()")
    public void beforePrintLog(JoinPoint joinPoint) throws IOException {
    
    
        // 获取执行 方法名
        String signature = joinPoint.getSignature().toString();
        int index = signature.lastIndexOf(".");
        String methodName = signature.substring(index);
        // 获取当前时间
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = df.format(new Date());
        // 记录日志
        log(methodName, "开始执行", time);
    }

    /**
     * 后置通知
     */
    @AfterReturning("pointcut()")
    public void afterReturningPrintLog(JoinPoint joinPoint) throws IOException {
    
    
        // 获取执行方法名
        String signature = joinPoint.getSignature().toString();
        int index = signature.lastIndexOf(".");
        String methodName = signature.substring(index);
        // 获取当前时间
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = df.format(new Date());
        // 记录日志
        log(methodName, "结束执行", time);
    }

    /**
     * 异常通知
     */
    @AfterThrowing("pointcut()")
    public void afterThrowingPrintLog(JoinPoint joinPoint) throws IOException {
    
    
        // 获取执行方法名
        String signature = joinPoint.getSignature().toString();
        System.out.println(signature);
        int index = signature.lastIndexOf(".");
        System.out.println(index);
        String methodName = signature.substring(index);
        // 获取当前时间
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = df.format(new Date());
        // 记录日志
        log(methodName, "出现异常", time);
    }

    /**
     * 最终通知
     */
    @After("pointcut()")
    public void afterPrintLog(JoinPoint joinPoint) throws IOException{
    
    
        // 获取执行方法名
        String signature = joinPoint.getSignature().toString();
        int index = signature.lastIndexOf(".");
        String methodName = signature.substring(index);
        // 获取当前时间
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = df.format(new Date());
        // 记录日志
        log(methodName, "最终通知", time);
    }

    /**
     * 环绕通知
     */
    @Around("pointcut()")
    public Object aroundPrintLog(ProceedingJoinPoint pjp) {
    
    
        Object rtValue = null;
        try {
    
    
            Object[] args = pjp.getArgs();//得到方法执行所需的参数
            System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。前置");
            rtValue = pjp.proceed(args);//明确调用业务层方法(切入点方法)
            System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。后置");
            return rtValue;
        } catch (Throwable t) {
    
    
            System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。异常");
            throw new RuntimeException(t);
        } finally {
    
    
            System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。最终");
        }
    }
}

2.3 Spring配置类

package com.lrm.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan(basePackages = {
    
    "com.lrm"})
@EnableAspectJAutoProxy
public class SpringConfig {
    
    

}

2.4 Dao类

package com.lrm.dao;

import org.springframework.stereotype.Repository;

@Repository(value = "userDaoImpl")
public class UserDaoImpl implements UserDao {
    
    
    @Override
    public void add() {
    
    
        System.out.println("dao add...");
    }
}

2.5 Service类

package com.lrm.service;

import com.lrm.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class UserService {
    
    


    @Autowired  //根据类型进行注入
    @Qualifier(value = "userDaoImpl") //根据名称进行注入
    private UserDao userDao;

    public void add() {
    
    
        System.out.println("service add...");
        userDao.add();
    }
}

2.6 Controller类

package com.lrm.controller;

import com.lrm.config.SpringConfig;
import com.lrm.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    
    

    @Test
    public void test1() {
    
    
        //加载配置类
        ApplicationContext context
                = new AnnotationConfigApplicationContext(SpringConfig.class);
        UserService userService = context.getBean("userService", UserService.class);
        userService.add();
    }

}

结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Orange_minger/article/details/114645059