@Aspect @Pointcut
时间: 2023-10-06 15:09:54 浏览: 119
@Aspect和@Pointcut是Spring框架中用于实现面向切面编程的注解。@Aspect表示一个切面,它是一个横切进业务的对象,包含切入点和通知。@Pointcut表示切入点,用于指定需要切入的位置,比如某些类或方法。
在使用@Aspect注解时,需要配置文件启用注解支持。例如,在配置文件中添加<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>来开启AOP注解。需要注意的是,如果需要切入Controller,则在对应的配置文件中添加该配置;如果是切入Service等其他应用,则在另一个配置文件中添加。
在微服务开发中,特别是使用SpringCloud/Springboot框架时,AOP的应用非常广泛。@Aspect注解方式是最流行的方式之一,它不仅功能强大,性能也优秀。因此,在开发过程中,可以结合具体案例详细介绍@Aspect方式的切面的使用。
相关问题
@Pointcut @Aspect与@Before结合使用
在Spring AOP中,@Pointcut和@Aspect注解一起使用可以定义切点和切面。@Pointcut注解定义了一个切点,而@Aspect注解定义了一个切面,切面包含了多个通知(Advice),例如@Before、@After、@AfterReturning、@AfterThrowing和@Around。
@Before通知是在目标方法执行前执行的通知,可以用来验证参数、记录日志等操作。要在@Before注解中指定切点表达式,以通知哪些方法执行该通知。
下面是一个示例:
```
@Aspect
@Component
public class MyAspect {
@Pointcut("execution(* com.example.service.UserService.addUser(..))")
public void addUserPointcut() {}
@Before("addUserPointcut()")
public void logBeforeAddUser(JoinPoint joinPoint) {
System.out.println("Before adding user...");
}
}
```
在上面的代码中,@Pointcut注解定义了一个切点,它匹配UserService类中的addUser方法。@Before注解指定了切点表达式addUserPointcut(),表示在addUser方法执行前执行logBeforeAddUser方法。
生成一个包含@Pointcut,@Advice,@Aspect的AOP简单框架
这里提供一个简单的AOP框架实现,包含@Pointcut,@Advice,@Aspect三个注解。
1. 定义@Pointcut注解
```java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Pointcut {
String value() default "";
}
```
2. 定义@Advice注解
```java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Advice {
String value() default "";
}
```
3. 定义@Aspect注解
```java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Aspect {
}
```
4. 定义切面类
```java
@Aspect
public class MyAspect {
@Pointcut("execution(* com.example.demo.service.*.*(..))")
public void pointcut() {}
@Advice("before")
public void beforeAdvice() {
System.out.println("before advice");
}
@Advice("after")
public void afterAdvice() {
System.out.println("after advice");
}
}
```
5. 定义目标类
```java
@Service
public class MyService {
public void doSomething() {
System.out.println("do something");
}
}
```
6. 实现AOP框架
```java
public class AopFramework {
public static void run(Class<?> targetClass) {
// 获取所有切面类
List<Class<?>> aspectClasses = getAspectClasses(targetClass);
// 创建所有切面类的实例
List<Object> aspectInstances = createAspectInstances(aspectClasses);
// 获取所有目标类的方法
Method[] targetMethods = targetClass.getDeclaredMethods();
// 遍历所有目标类的方法
for (Method targetMethod : targetMethods) {
// 遍历所有切面类
for (Object aspectInstance : aspectInstances) {
// 获取切点方法
Method pointcutMethod = getPointcutMethod(aspectInstance);
if (pointcutMethod != null) {
try {
// 调用切点方法
pointcutMethod.invoke(aspectInstance);
// 获取前置通知方法
Method beforeAdviceMethod = getBeforeAdviceMethod(aspectInstance);
if (beforeAdviceMethod != null) {
// 调用前置通知方法
beforeAdviceMethod.invoke(aspectInstance);
}
// 调用目标方法
targetMethod.invoke(targetClass.newInstance());
// 获取后置通知方法
Method afterAdviceMethod = getAfterAdviceMethod(aspectInstance);
if (afterAdviceMethod != null) {
// 调用后置通知方法
afterAdviceMethod.invoke(aspectInstance);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
private static List<Class<?>> getAspectClasses(Class<?> targetClass) {
List<Class<?>> aspectClasses = new ArrayList<>();
Package targetPackage = targetClass.getPackage();
String targetPackageName = targetPackage.getName();
String aspectPackageName = targetPackageName + ".aspect";
try {
Reflections reflections = new Reflections(aspectPackageName);
Set<Class<?>> annotatedClasses = reflections.getTypesAnnotatedWith(Aspect.class);
aspectClasses.addAll(annotatedClasses);
} catch (Exception e) {
e.printStackTrace();
}
return aspectClasses;
}
private static List<Object> createAspectInstances(List<Class<?>> aspectClasses) {
List<Object> aspectInstances = new ArrayList<>();
for (Class<?> aspectClass : aspectClasses) {
try {
Object aspectInstance = aspectClass.newInstance();
aspectInstances.add(aspectInstance);
} catch (Exception e) {
e.printStackTrace();
}
}
return aspectInstances;
}
private static Method getPointcutMethod(Object aspectInstance) {
Method[] methods = aspectInstance.getClass().getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(Pointcut.class)) {
return method;
}
}
return null;
}
private static Method getBeforeAdviceMethod(Object aspectInstance) {
return getAdviceMethod(aspectInstance, "before");
}
private static Method getAfterAdviceMethod(Object aspectInstance) {
return getAdviceMethod(aspectInstance, "after");
}
private static Method getAdviceMethod(Object aspectInstance, String adviceType) {
Method[] methods = aspectInstance.getClass().getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(Advice.class)) {
Advice advice = method.getAnnotation(Advice.class);
if (advice.value().equals(adviceType)) {
return method;
}
}
}
return null;
}
}
```
7. 测试AOP框架
```java
public class AopTest {
public static void main(String[] args) {
AopFramework.run(MyService.class);
}
}
```
输出结果:
```
before advice
do something
after advice
```
阅读全文