AOP联盟规范了一套用于规范AOP实现的底层API,通过这些统一的底层API,可以使得各个AOP实现及工具产品之间实现相互移植。这些API主要以标准接口的形式提供,是AOP编程思想所要解决的横切交叉关注点问题各部件的最高抽象。无论是Spring的AOP框架,还是开源的aspect框架,都是直接以这些API为基础所构建。
Spring实现AOP都是基于接口形式的
- public interface GreetingInterface {
- String sayHello(String name);
- }
- public class GreetingImpl implements GreetingInterface {
-
- @Override
- public String sayHello(String name) {
- System.out.println("Hello! " + name);
- return name;
- }
- }
- /** 前置通知 */
- public class GreetingBeforeAdvice implements MethodBeforeAdvice{
-
- @Override
- public void before(Method method, Object[] args, Object target) throws Throwable {
- System.out.println(">>>>>>>>>>>>>>>>>>Before Start>>>>>>>>>>>>>>>>>>");
- System.out.println("Method Name: " + method.getName());
- System.out.println("args:" + Arrays.toString(args));
- System.out.println("Target : " + target.getClass().getName());
- System.out.println("<<<<<<<<<<<<<<<<<<Before End<<<<<<<<<<<<<<<<<<<<<<<<");
- }
-
- }
- /** 后置返回通知*/
- public class GreetingAfterAdvice implements AfterReturningAdvice {
-
- @Override
- public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
- System.out.println(">>>>>>>>>>>>>>>>After Start>>>>>>>>>>>>>>>>>>>>");
- System.out.println("returnValue:" + returnValue);
- System.out.println("Method Name: " + method.getName());
- System.out.println("args:" + Arrays.toString(args));
- System.out.println("Target : " + target.getClass().getName());
- System.out.println("<<<<<<<<<<<<<<<<<After End<<<<<<<<<<<<<<<<<<<<<<");
- }
-
- }
- /** 异常通知 */
- public class GreetingThrowAdvice implements ThrowsAdvice {
-
- public void afterThrowing(Method method, Object[] args, Object target, Exception e) {
- System.out.println("---------- Throw Exception ----------");
- System.out.println("Target Class: " + target.getClass().getName());
- System.out.println("Method Name: " + method.getName());
- System.out.println("Exception Message: " + e.getMessage());
- System.out.println("-------------------------------------");
- }
- }
- /** 环绕通知*/
- public class GreetingAroundAdvice implements MethodInterceptor {
-
- @Override
- public Object invoke(MethodInvocation invocation) throws Throwable {
- before();
- Object result = invocation.proceed();
- after();
- return result;
- }
-
- private void before() {
- System.out.println("---->>>>Before");
- }
-
- private void after() {
- System.out.println("---->>>>After");
- }
- }
- public class AdviceClient {
-
- public static void main(String[] args) {
- ProxyFactory proxyFactory = new ProxyFactory(); // 创建代理工厂
- proxyFactory.setTarget(new GreetingImpl()); // 射入目标类对象
- proxyFactory.addAdvice(new GreetingBeforeAdvice()); // 添加前置通知
- proxyFactory.addAdvice(new GreetingAfterAdvice()); // 添加后置通知
- proxyFactory.addAdvice(new GreetingAroundAdvice()); // 添加环绕通知
- proxyFactory.addAdvice(new GreetingThrowAdvice()); // 添加抛出通知
- proxyFactory.setOptimize(true);//使用CGLIB动态代理
-
- GreetingInterface greeting = (GreetingInterface) proxyFactory.getProxy(); // 从代理工厂中获取代理
- greeting.sayHello("Jack"); // 调用代理的方法
-
- }
- }
第一种方式:
第二种方式:
第三种方式
- package com.somnus.spring.namespace.aop;
-
- import java.util.Arrays;
-
- import org.aspectj.lang.JoinPoint;
- import org.aspectj.lang.ProceedingJoinPoint;
- import org.aspectj.lang.reflect.MethodSignature;
-
- public class GreetAspector {
-
- /**@前置通知
- * 方法开始之前执行一段代码
- * @param joinPoint
- */
- public void before(JoinPoint joinPoint) {
- String methodName = joinPoint.getSignature().getName();
- Object[] args = joinPoint.getArgs();
- System.out.println("The method 【" + methodName + "】 begins with " + Arrays.asList(args));
- }
-
- /**@后置最终通知
- * 方法执行之后执行一段代码
- * 无论该方法是否出现异常
- * @param joinPoint
- */
- public void after(JoinPoint joinPoint) {
- String methodName = joinPoint.getSignature().getName();
- Object[] args = joinPoint.getArgs();
- System.out.println("The method 【" + methodName + "】 ends with " + Arrays.asList(args));
- }
-
- /**@后置返回通知
- * 方法正常结束后执行的代码,不包括抛出异常的情况
- * 返回通知是可以访问到方法的返回值的
- * @param joinPoint
- * @param result
- */
- public void afterReturning(JoinPoint joinPoint,Object result) {
- String methodName = joinPoint.getSignature().getName();
- System.out.println("The method 【" + methodName + "】 return with " + result);
- }
-
- /**@后置异常通知
- * 在方法出现异常时会执行的代码
- * 可以访问到异常对象,可以指定在出现特定异常时在执行通知代码
- * @param joinPoint
- * @param ex
- */
- public void afterThrowing(JoinPoint joinPoint, Exception ex) {
- String methodName = joinPoint.getSignature().getName();
- System.out.println("The method " + methodName + " occurs exception: " + ex);
- }
-
- /**@环绕通知
- * 环绕通知需要携带ProceedingJoinPoint类型的参数
- * 环绕通知类似于动态代理的全过程:ProceedingJoinPoint类型的参数可以决定是否执行目标方法。
- * 而且环绕通知必须有返回值,返回值即为目标方法的返回值
- * @param pjp
- * @return
- * @throws Throwable
- */
- public Object around(ProceedingJoinPoint pjp) throws Throwable {
- Object result = null;
- System.out.println("target:"+pjp.getTarget());
- MethodSignature signature = (MethodSignature) pjp.getSignature();
- String methodName = signature.getName();
- //执行目标方法
- try {
-
- System.out.println("ARROUND-->The method 【" + methodName + "】 begins with 【" + Arrays.asList(pjp.getArgs()) +"】");
- result = pjp.proceed();
- } catch (Throwable e) {
-
- System.out.println("ARROUND-->The method 【" + methodName + "】 occurs expection : 【" + e +"】");
- throw new RuntimeException(e);
- }
-
- System.out.println("ARROUND-->The method 【" + methodName + "】 return with 【" + result +"】");
- return result;
- }
-
- }
- package com.somnus.spring.annotation.aop;
-
- import java.lang.reflect.Method;
- import java.util.Arrays;
-
- import org.aspectj.lang.JoinPoint;
- import org.aspectj.lang.ProceedingJoinPoint;
- import org.aspectj.lang.annotation.After;
- import org.aspectj.lang.annotation.AfterReturning;
- import org.aspectj.lang.annotation.AfterThrowing;
- import org.aspectj.lang.annotation.Around;
- import org.aspectj.lang.annotation.Aspect;
- import org.aspectj.lang.annotation.Before;
- import org.aspectj.lang.annotation.DeclareParents;
- import org.aspectj.lang.reflect.MethodSignature;
- import org.springframework.stereotype.Component;
-
- @Aspect
- @Component
- public class GreetAspector {
- /**@前置通知
- * 方法开始之前执行一段代码
- * @param joinPoint
- */
- @Before("execution(* com.somnus.spring.annotation.aop.GreetingImpl.*(..))")
- public void before(JoinPoint point) {
- String methodName = point.getSignature().getName();
- Method method = ((MethodSignature) point.getSignature()).getMethod();
- System.out.println(method.getName());
- Object[] args = point.getArgs();
- System.out.println("The method 【" + methodName + "】 begins with " + Arrays.asList(args));
- }
-
- /**@后置最终通知
- * 方法执行之后执行一段代码
- * 无论该方法是否出现异常
- * @param joinPoint
- */
- @After("execution(* com.somnus.spring.annotation.aop.GreetingImpl.*(..))")
- public void after(JoinPoint point) {
- String methodName = point.getSignature().getName();
- Object[] args = point.getArgs();
- System.out.println("The method 【" + methodName + "】 ends with " + Arrays.asList(args));
- }
-
- /**@后置返回通知
- * 方法正常结束后执行的代码,不包括抛出异常的情况
- * 返回通知是可以访问到方法的返回值的
- * @param joinPoint
- * @param result
- */
- @AfterReturning(value="execution(* com.somnus.spring.annotation.aop.GreetingImpl.*(..))",returning="result")
- public void afterReturning(JoinPoint point,Object result) {
- String methodName = point.getSignature().getName();
- System.out.println("The method 【" + methodName + "】 return with " + result);
- }
-
- /**@后置异常通知
- * 在方法出现异常时会执行的代码
- * 可以访问到异常对象,可以指定在出现特定异常时在执行通知代码
- * @param joinPoint
- * @param ex
- */
- @AfterThrowing(value="execution(* com.somnus.spring.annotation.aop.GreetingImpl.*(..))", throwing="ex")
- public void afterThrowing(JoinPoint point, Exception ex) {
- String methodName = point.getSignature().getName();
- System.out.println("The method " + methodName + " occurs exception: " + ex);
- }
-
- /**@环绕通知
- * 环绕通知需要携带ProceedingJoinPoint类型的参数
- * 环绕通知类似于动态代理的全过程:ProceedingJoinPoint类型的参数可以决定是否执行目标方法。
- * 而且环绕通知必须有返回值,返回值即为目标方法的返回值
- * @param pjp
- * @return
- * @throws Throwable
- */
- @Around("execution(* com.somnus.spring.annotation.aop.GreetingImpl.*(..))")
- public Object around(ProceedingJoinPoint point) throws Throwable {
- Object result = null;
- System.out.println("target:" + point.getTarget());
- Method method = ((MethodSignature) point.getSignature()).getMethod();
- System.out.println(method.getName());
- String methodName = point.getSignature().getName();
- //执行目标方法
- try {
- //前置通知
- System.out.println("ARROUND-->The method 【" + methodName + "】 begins with 【" + Arrays.asList(point.getArgs()) +"】");
- result = point.proceed();
- } catch (Throwable e) {
- //后置异常通知【在方法出现异常时会执行的代码】
- System.out.println("ARROUND-->The method 【" + methodName + "】 occurs expection : 【" + e +"】");
- throw new RuntimeException(e);
- }
- //后置返回通知【方法正常结束后执行的代码,不包括抛出异常的情况】
- System.out.println("ARROUND-->The method 【" + methodName + "】 return with 【" + result +"】");
- return result;
- }
-
- /**
- * 用 AOP 的行话来讲,对方法的增强叫做 Weaving(织入),
- * 而对类的增强叫做 Introduction(引入)。
- * 而 Introduction Advice(引入增强)就是对类的功能增强,
- * 它也是 Spring AOP 提供的最后一种增强
- */
- @DeclareParents(value = "com.somnus.spring.annotation.aop.GreetingImpl", defaultImpl = ApologyImpl.class)
- private Apology apology;
- }