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">
<parent>
<artifactId>learn</artifactId>
<groupId>com.evan</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-aop-basic-learn</artifactId>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring aop支持-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectjweaver.version}</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<spring.version>5.3.9</spring.version>
<aspectjweaver.version>1.9.6</aspectjweaver.version>
</properties>
</project>
业务
package com.evan.service;
import com.evan.entity.User;
import java.util.List;
public interface UserService {
List<User> findUserList();
void addUser();
}
package com.evan.service.impl;
import com.evan.annotation.MyAnnotation;
import com.evan.entity.User;
import com.evan.service.UserService;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@MyAnnotation("evan")
@Override
public List<User> findUserList() {
System.out.println("执行方法:findUserList");
return Collections.singletonList(new User("evan", 18));
}
/**
* add user
*/
@Override
public void addUser() {
System.out.println("execute method: addUser");
// do something
}
}
自定义注解
package com.evan.annotation;
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation {
String value() default "";
}
切面
package com.evan.aspect;
import com.evan.annotation.MyAnnotation;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import java.lang.reflect.Method;
@Aspect
public class MyAnnotationAspect {
@Pointcut("@annotation(com.evan.annotation.MyAnnotation)")
private void pointCut() {
}
@Around("pointCut()")
public Object doAround(ProceedingJoinPoint jointPoint) throws NoSuchMethodException {
System.out.println("环绕通知: 进入方法");
// 获取当前访问的class类及类名
Class<?> clazz = jointPoint.getTarget().getClass();
String clazzName = jointPoint.getTarget().getClass().getName();
// 获取访问的方法名
String methodName = jointPoint.getSignature().getName();
// 获取方法所有参数及其类型
Object[] args = jointPoint.getArgs();
System.out.println("获取当前访问的class类及类名" + clazzName);
System.out.println("获取访问的方法名" + methodName);
System.out.println("获取方法所有参数及其类型" + args);
Class[] argClz = ((MethodSignature) jointPoint.getSignature()).getParameterTypes();
// 获取访问的方法对象
Method method = clazz.getDeclaredMethod(methodName, argClz);
System.out.println("获取访问的方法对象" + method);
// 判断当前访问的方法是否存在指定注解
if (method.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
// 获取注解标识值与注解描述
String value = annotation.value();
System.out.println(value);
// 执行目标方法
Object o = null;
try {
o = jointPoint.proceed();
System.out.println("打印方法是执行返回结果:" + o.toString());
return o;
} catch (Throwable e) {
//throw new RuntimeException(e);
System.out.println(e.getMessage());
} finally {
System.out.println("环绕通知: 退出方法");
}
}
return null;
}
}
配置类
package com.evan.config;
import com.evan.aspect.MyAnnotationAspect;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configurable
@EnableAspectJAutoProxy
@ComponentScan("com.evan")
public class AnnotationConfig {
@Bean
public MyAnnotationAspect myAnnotationAspect() {
return new MyAnnotationAspect();
}
}
测试类
package com.evan;
import com.evan.config.AnnotationConfig;
import com.evan.config.MyConfig;
import com.evan.entity.User;
import com.evan.service.ArithmeticCalculator;
import com.evan.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import java.util.List;
public class AnnotationTest {
@Test
public void test01() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnnotationConfig.class);
UserService userService = context.getBean(UserService.class);
List<User> userList = userService.findUserList();
System.out.println(userList);
}
}
测试结果
环绕通知: 进入方法
获取当前访问的class类及类名com.evan.service.impl.UserServiceImpl
获取访问的方法名findUserList
获取方法所有参数及其类型[Ljava.lang.Object;@16c069df
获取访问的方法对象public java.util.List com.evan.service.impl.UserServiceImpl.findUserList()
evan
执行方法:findUserList
打印方法是执行返回结果:[User(name=evan, age=18)]
环绕通知: 退出方法
[User(name=evan, age=18)]