- 代码混乱:越来越多的非业务需求(日志和验证等)加入后, 原有的业务方法急剧膨胀. 每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点.
- 代码分散: 以日志需求为例, 只是为了满足这个单一需求, 就不得不在多个模块(方法)里多次重复相同的日志代码. 如果日志需求发生变化, 必须修改所有模块.
动态代理:
package com.atguigu.spring.aop; public interface ArithmeticCalculator1 { int add(int i ,int j); int sub(int i ,int j); int mul(int i, int j); int div(int i, int j); }
package com.atguigu.spring.aop; import org.springframework.stereotype.Component; @Component("arithmeticCalculator") public class ArithmeticCalculatorImpl1 implements ArithmeticCalculator1 { @Override public int add(int i, int j) { int result = i + j; return result; } @Override public int sub(int i, int j) { int result = i - j; return result; } @Override public int mul(int i, int j) { int result = i * j; return result; } @Override public int div(int i, int j) { int result = i / j; return result; } }
package com.atguigu.spring.aop; import org.springframework.stereotype.Component; @Component("arithmeticCalculator") public class ArithmeticCalculatorLoggingImpl1 implements ArithmeticCalculator1 { @Override public int add(int i, int j) { System.out.println("The method add begins with[" + i + "," + j + "]"); int result = i + j; System.out.println("The method add end with[" + result); return result; } @Override public int sub(int i, int j) { System.out.println("The method sub begins with[" + i + "," + j + "]"); int result = i - j; System.out.println("The method sub end with[" + result); return result; } @Override public int mul(int i, int j) { System.out.println("The method mul begins with[" + i + "," + j + "]"); int result = i * j; System.out.println("The method mul end with[" + result); return result; } @Override public int div(int i, int j) { System.out.println("The method div begins with[" + i + "," + j + "]"); int result = i / j; System.out.println("The method div end with[" + result); return result; } }
package com.atguigu.spring.aop; import java.lang.reflect.Array; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Arrays; import org.springframework.jmx.access.InvalidInvocationException; public class ArithmeticCalculatorLoggingProxy { //要代理的对象 private ArithmeticCalculator1 target; public ArithmeticCalculatorLoggingProxy(ArithmeticCalculator1 target){ this.target = target; } public ArithmeticCalculator1 getLoggingProxy() { ArithmeticCalculator1 proxy = null; //代理对象由哪一个类加载器负责加载 ClassLoader loader = target.getClass().getClassLoader(); //代理对象的类型,即其中有哪些方法 Class [] interfaces = new Class[]{ArithmeticCalculator1.class}; //当调用代理对象其中的方法时,该执行的代码 InvocationHandler h = new InvocationHandler() { /** * proxy:正在还回的那个代理对象,一般情况下,在invoke方法中都不使用该对象 * method:正在被调用的方法 * args:调用方法时,传入的参数 * */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); //日志 System.out.println("The method" + methodName + "begins with" + Arrays.asList(args)); //执行方法 Object result = method.invoke(target, args); //日志 System.out.println(""); System.out.println("The method" + methodName + "begins with" + result); return result; } }; proxy = (ArithmeticCalculator1) Proxy.newProxyInstance(loader, interfaces, h); return proxy; } }
package com.atguigu.spring.aop; public class Main { public static void main(String[] args) { ArithmeticCalculator1 target = new ArithmeticCalculatorImpl1(); ArithmeticCalculator1 proxy = (ArithmeticCalculator1) new ArithmeticCalculatorLoggingProxy(target).getLoggingProxy(); int result = proxy.add(1, 2); System.out.println("-->" + result); int result1 = proxy.div(4, 2); System.out.println("-->" + result1); // ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); // ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) ctx.getBean("arithmeticCalculator"); // // System.out.println(arithmeticCalculator.getClass().getName()); // // int result = arithmeticCalculator.add(1, 2); // System.out.println("result:" + result); // // result = arithmeticCalculator.div(1000, 10); // System.out.println("result:" + result); } }
结果:
The methodaddbegins with[1, 2] The methodaddbegins with3 -->3 The methoddivbegins with[4, 2] The methoddivbegins with2 -->2