@Aspect和@advice
时间: 2023-11-03 12:01:53 浏览: 88
@Aspect是一个用于定义切面的注解,它表示一个类是切面。@Advice是一个用于定义通知的注解,它表示一个方法是通知。
在使用AspectJ时,我们可以使用@Aspect注解来定义切面,然后在其中使用@Advice注解来定义通知。通知可以分为前置通知(@Before)、后置通知(@After)、返回通知(@AfterReturning)、异常通知(@AfterThrowing)和环绕通知(@Around),每种通知都有不同的用途。
例如,下面的代码定义了一个切面和一个前置通知:
```
@Aspect
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Logging before method: " + joinPoint.getSignature().getName());
}
}
```
这个切面会在service包中的所有方法执行前打印一条日志。在这个例子中,@Before注解表示这是一个前置通知,它的参数表示切入点表达式,它指定了哪些方法会被切入。在这个例子中,切入点表达式指定了所有service包中的方法。
总之,@Aspect和@Advice是AspectJ框架中非常重要的注解,它们用于定义切面和通知,可以帮助我们实现各种不同的功能,如日志记录、性能监控等。
相关问题
生成一个包含@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
```
@Aspect和@EnableAspectJAutoProxy
@Aspect是Spring框架中用于定义切面的注解,标注在类上表示该类为切面类。在该类中,可以定义多个通知(Advice),例如@Before、@After、@Around等,用于在目标方法执行前、执行后、或在方法执行过程中进行拦截和增强。
@EnableAspectJAutoProxy是Spring框架中用于开启AspectJ注解支持的注解,标注在配置类上。当使用@EnableAspectJAutoProxy注解开启AspectJ注解支持后,Spring容器会自动扫描所有带有@Aspect注解的类,并将其注册成切面类,同时在应用程序中自动创建代理对象,实现AOP的功能。
阅读全文