- 代码混乱:越来越多的非业务需求(日志和验证等)加入后, 原有的业务方法急剧膨胀. 每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点.
- 代码分散: 以日志需求为例, 只是为了满足这个单一需求, 就不得不在多个模块(方法)里多次重复相同的日志代码. 如果日志需求发生变化, 必须修改所有模块.
动态代理:
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