目的
AOP(面向切面编程)相对于OOP(面向对象编程),OOP采用继承与实现接口的方法增加了耦合度,而AOP对切面进行声明,采用拦截的方法进行一类操作,降低了耦合度与代码的重复。
两种拦截方法
使用注解拦截
首先声明一个注解
package com.cenobitor.aop.annotation;
import java.lang.annotation.*;
@Target(ElementType.METHOD) //作用目标为方法
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Documented //该注解将被包含在javadoc中
public @interface Action {
String name();
}
编写使用注解被拦截的类(由于注解作用目标为方法,只要在方法前加上注解名,并设定注解的属性即可)
package com.cenobitor.aop.service;
import com.cenobitor.aop.annotation.Action;
import org.springframework.stereotype.Service;
@Service
public class DemoAnnotationService {
@Action(name = "注解式拦截的add操作")
public void add(){}
}
使用方法规则拦截
编写使用方法规则被拦截类
简单的声明一个Bean
package com.cenobitor.aop.service;
import org.springframework.stereotype.Service;
@Service
public class DemoMethodService {
public void add(){}
}
切面编写
首先定义切点
package com.cenobitor.aop.aspect;
import com.cenobitor.aop.annotation.Action;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Aspect //这是一个切面
@Component
public class LogAspect {
//切点定义
@Pointcut("@annotation(com.cenobitor.aop.annotation.Action)")
public void annotationPoinCut(){}
//注解拦截
@After("annotationPoinCut()") //使用切点
public void after(JoinPoint joinPoint){
//反射
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Action action = method.getAnnotation(Action.class);
System.out.println("注解式拦截 "+action.name());
}
//方法规则拦截
// 注明一个建言,直接使用拦截规则作为参数
@Before("execution(* com.cenobitor.aop.service.DemoMethodService.*(..))")
public void before(JoinPoint joinPoint){
//反射
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
System.out.println("方法规则式拦截,"+method.getName());
}
}
区别
采用方法拦截时需指定拦截的具体对象及具体方法
而当编写好注解及拦截规则后,之后再有相同需求时只需要在方法或对象前加上注解即可,无需进行其他操作,减少了代码量,而且使用方便。