标签:
1 public interface ArithmeticCalculator { 2 3 int add(int i, int j); 4 int sub(int i, int j); 5 6 int mul(int i, int j); 7 int div(int i, int j); 8 9 }
1 @Component("arithmeticCalculator") 2 public class ArithmeticCalculatorImpl implements ArithmeticCalculator { 3 4 @Override 5 public int add(int i, int j) { 6 int result = i + j; 7 return result; 8 } 9 10 @Override 11 public int sub(int i, int j) { 12 int result = i - j; 13 return result; 14 } 15 16 @Override 17 public int mul(int i, int j) { 18 int result = i * j; 19 return result; 20 } 21 22 @Override 23 public int div(int i, int j) { 24 int result = i / j; 25 return result; 26 } 27 28 }
1 public class ArithmeticCalculatorLoggingImpl implements ArithmeticCalculator { 2 3 4 @Override 5 public int add(int i, int j) { 6 System.out.println("The method add begins with [" + i + "," + j + "]"); 7 int result = i + j; 8 System.out.println("The method add ends with " + result); 9 return result; 10 } 11 12 @Override 13 public int sub(int i, int j) { 14 System.out.println("The method sub begins with [" + i + "," + j + "]"); 15 int result = i - j; 16 System.out.println("The method sub ends with " + result); 17 return result; 18 } 19 20 @Override 21 public int mul(int i, int j) { 22 System.out.println("The method mul begins with [" + i + "," + j + "]"); 23 int result = i * j; 24 System.out.println("The method mul ends with " + result); 25 return result; 26 } 27 28 @Override 29 public int div(int i, int j) { 30 System.out.println("The method div begins with [" + i + "," + j + "]"); 31 int result = i / j; 32 System.out.println("The method div ends with " + result); 33 return result; 34 } 35 36 }
1 public class ArithmeticCalculatorLoggingProxy { 2 3 4 private ArithmeticCalculator target; 5 6 public ArithmeticCalculatorLoggingProxy(ArithmeticCalculator target) { 7 super(); 8 this.target = target; 9 } 10 11 12 public ArithmeticCalculator getLoggingProxy(){ 13 ArithmeticCalculator proxy = null; 14 15 ClassLoader loader = target.getClass().getClassLoader(); 16 Class [] interfaces = new Class[]{ArithmeticCalculator.class}; 17 InvocationHandler h = new InvocationHandler() { 18 /*method 方法 19 *args 参数 20 * */ 21 @Override 22 public Object invoke(Object proxy, Method method, Object[] args) 23 throws Throwable { 24 String methodName = method.getName(); 25 26 //前置通知 27 System.out.println("[before] The method " + methodName + " begins with " + Arrays.asList(args)); 28 29 Object result = null; 30 try { 31 32 result = method.invoke(target, args);//返回通知 33 34 } catch (NullPointerException e) { 35 e.printStackTrace(); 36 //异常通知 37 } 38 //后置通知 39 System.out.println("[after] The method ends with " + result); 40 41 return result; 42 } 43 }; 44 45 proxy = (ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h); 46 47 return proxy; 48 } 49 }
1 /** 2 * AOP 3 * 1. 导入jar包 4 * com.springsource.net.sf.cglib-2.2.0.jar 5 * com.springsource.org.aopalliance-1.0.0.jar 6 * com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar 7 * spring-aspects-4.0.0.RELEASE.jar 8 * 9 * 2. 在配置文件中加入AOP的命名空间 10 * xmlns:aop="http://www.springframework.org/schema/aop" 11 * 12 * 3. 基于注解的方式 13 * <context:component-scan base-package="com.atguigu.spring.aop"></context:component-scan> 14 * <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 15 * 16 * 4.把横切关注点的代码抽象到切面的类中 17 * @Aspect 18 * @Component 19 * public class LoggingAspect {} 20 * 21 * 5.AspectJ支持5种类型的通知注解 22 * @Before()前置通知,在方法开始前执行 23 * @After()后置通知,在方法执行后执行,无论抛异常都会执行;不能访问方法执行的结果 24 * @AfterRunning()返回通知,在方法返回结果后执行(即方法正常结束后才执行);可以得到方法执行的结果 25 * @AfterThrowing()异常通知,在方法抛出异常时执行 26 * @Around()环绕通知,围绕着方法执行 27 * 6.AspectJ表达式 28 * execution(public int com.aop.beans.ArithmeticCalculator.*(int, int)) 29 * execution(* com.aop.beans.*.*(int, int)) 30 * 31 * 7.JoinPoint 32 * 通过他可以得到方法的信息 33 */ 34 35 //把这个类放入到IOC容器中@Component;再声明为一个切面@Aspect 36 @Aspect 37 @Component 38 public class LoggingAspect { 39 //该方法是一个前置通知,即在目标方法开始前执行@Before() 40 @Before("execution(public int com.aop.beans.ArithmeticCalculator.*(int, int))") 41 public void beforeMethod(JoinPoint joinPoint){ 42 String methodName = joinPoint.getSignature().getName();//得到方法名 43 Object [] args = joinPoint.getArgs();//得到参数 44 45 System.out.println("前置通知:The method " + methodName + " begins with " + Arrays.asList(args)); 46 } 47 48 @After("execution(* com.aop.beans.*.*(..))")//位置为这个包下的所有类、所有方法、不论参数是什么类型 49 public void afterMethod(JoinPoint joinPoint){ 50 String methodName = joinPoint.getSignature().getName(); 51 System.out.println("后置通知:The method " + methodName + " ends"); 52 } 53 54 55 @AfterReturning(value="execution(public int com.aop.beans.ArithmeticCalculator.*(int, int))", 56 returning="result") 57 public void afterReturning(JoinPoint joinPoint, Object result){ 58 String methodName = joinPoint.getSignature().getName(); 59 System.out.println("返回通知:The method " + methodName + " ends with " + result); 60 } 61 62 63 @AfterThrowing(value="execution(public int com.aop.beans.ArithmeticCalculator.*(int, int))", 64 throwing="e") 65 public void afterThrowing(JoinPoint joinPoint, Exception e){ 66 String methodName = joinPoint.getSignature().getName(); 67 System.out.println("异常通知:The method " + methodName + " occurs excetion:" + e); 68 } 69 70 /* 71 * 环绕通知功能相当于动态代理的全过程,需要有ProceedingJoinPoint 类型的参数; 72 * pjd 参数可以决定是否执行目标方法 73 * 环绕通知必须有返回值,返回值即为目标方法的返回值 74 * 75 * 76 @Around("execution(public int com.aop.beans.ArithmeticCalculator.*(int, int))") 77 public Object aroundMethod(ProceedingJoinPoint pjd){ 78 79 Object result = null;//返回值 80 String methodName = pjd.getSignature().getName();//得到方法名 81 82 try { 83 //前置通知 84 System.out.println("The method " + methodName + " begins with " + Arrays.asList(pjd.getArgs())); 85 result = pjd.proceed();//执行方法 //返回通知 86 System.out.println("The method " + methodName + " ends with " + result); 87 } catch (Throwable e) { 88 //异常通知 89 System.out.println("The method " + methodName + " occurs exception:" + e); 90 throw new RuntimeException(e); 91 } 92 //后置通知 93 System.out.println("The method " + methodName + " ends"); 94 95 return result; 96 } 97 */ 98 99 }
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/aop 9 http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 10 http://www.springframework.org/schema/context 11 http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 12 13 <!-- 自动扫描的包; 扫描@注解,添加到IOC容器中,让Spring管理--> 14 <context:component-scan base-package="com.aop.beans"></context:component-scan> 15 16 <!-- 使 AspectJ 的注解起作用 ; autoproxy自动代理--> 17 <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 18 19 </beans>
1 public class Main { 2 3 public static void main(String[] args) { 4 /*代理模式实现添加日志功能 5 ArithmeticCalculator arithmeticCalculator = new ArithmeticCalculatorImpl(); 6 arithmeticCalculator = new ArithmeticCalculatorLoggingProxy(arithmeticCalculator).getLoggingProxy(); 7 int result = arithmeticCalculator.add(11, 12); 8 System.out.println("result:" + result); 9 result = arithmeticCalculator.div(21, 3); 10 System.out.println("result:" + result); 11 */ 12 13 //AOP实现添加日志功能 14 ApplicationContext ctx = new ClassPathXmlApplicationContext("com/aop/beans/beans-aop.xml"); 15 ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) ctx.getBean("arithmeticCalculator"); 16 17 System.out.println(arithmeticCalculator.getClass().getName()); 18 19 int result = arithmeticCalculator.add(11, 12); 20 System.out.println("result:" + result); 21 result = arithmeticCalculator.div(21, 2); 22 System.out.println("result:" + result); 23 24 } 25 26 }
标签:
原文地址:http://www.cnblogs.com/wwzyy/p/5151471.html