文章目录
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();
}
}
结果: