AOP 面向切面编程,是 OOP (面向对象编程)的补充
术语
横切关注点:方法中非主要业务逻辑部分
比如运算的模块:有验证参数、执行方法前的操作、执行方法、执行方法后的操作,验证参数、执行方法前后的操作是横切关注点
比如权限验证模块:在执行增删改查等方法前要进行验证,主要业务逻辑其实是增删改查,验证权限是横切关注点
比如日志模块:执行某方法前后都要生成文件或者往文件写入记录,日志记录是横切关注点
切面:横切关注点的抽象到一个类中
就是把横切关注点封装成一个类,在主要业务逻辑执行根据情况来调用
声明切面的步骤:1,把该类放入 IOC 容器,进行管理;2,使用注解 @Aspect 表明这是一个切面
通知:是切面类中的方法,用于在目标方法执行时执行
前置通知(@Before):目标方法执行前
后置通知(@After):目标方法执行后,无论是否发生异常
返回通知(@AfterRunning):目标方法正常结束后执行,可以知道目标方法的返回值
异常通知(@AfterThrowing):目标方法产生异常时执行,可以访问异常对象,进行打印,也可以指定异常才执行
环绕通知@(Around):包含上面4种
声明通知的步骤:1,指明通知类型;2,指明目标方法;3,配置文件使通知生效
连接点:用于获取目标方法的详细信息,方法名,参数值;JoinPoint
示例:
/** * .切面类 * .第一步:添加 @Aspect 注解 * .第二步:添加 @Component 注解 * .第三步:指明通知类型和目标方法 */ @Aspect @Component public class AspectCompute { /** * .第一个 * :任意返回值 * .第二个 * :com.weipai.service 包下的任意类 * .第三个 * :任意方法 * .(..):所有参数,不区分类型 */ @Before("execution(* com.weipai.service.*.*(..))") public void beforeMethod(JoinPoint info) { // 获取目标方法名 String methodName = info.getSignature().getName(); // 获取目标方法参数值 List<Object> args = Arrays.asList(info.getArgs()); System.out.println("前置通知,方法名:" + methodName + ",参数:" + args); } }
@Service("compute") public class Compute { public void add(int i, int j, String k) { System.out.println(i + j + k); } }
<!-- 扫描,支持spring注解 --> <context:component-scan base-package="com.weipai.aspect,com.weipai.service" /> <!-- 配置 aspect :自动生成代理类 --> <aop:aspectj-autoproxy />
public class ComputeTest extends TestCase { private ApplicationContext ctx; private Compute comp; protected void setUp() throws Exception { ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); comp = (Compute) ctx.getBean("compute"); } public void testAdd() { comp.add(1, 3, "hello"); } }