1、动态代理
越来越多的非业务需求(日志和验证)加入后,原有的计算器方法急剧膨胀。
每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点。以日志需求为例,
只是为了满足这个单一需求,就不得不在多个模块里多次重复相同的日志代码。
如果日志需求发生变化,必须修改所以模块。
关于动态代理的细节
1.需要一个被代理的对象。
2.类加载器通常是和被代理对象使用相同的类加载器。
3.一般地,Proxy.newInstance()的返回值是一个被代理对象实现的接口的类型。
当然也可以是其他的接口的类型
//被代理的接口
public interface ArithmeticCalculator {
public int add(int a, int b);
public int sub(int a, int b);
public int mul(int a, int b);
public int div(int a, int b);
}
//被代理的实现类
public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
@Override
public int add(int a, int b) {
return a + b;
}
@Override
public int sub(int a, int b) {
return a - b;
}
@Override
public int mul(int a, int b) {
return a * b;
}
@Override
public int div(int a, int b) {
return a / b;
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import org.junit.Test;
public class TestProxy {
@Test
public void testProxy(){
ArithmeticCalculator target = new ArithmeticCalculatorImpl();
//创建代理类
final ArithmeticCalculator proxy = (ArithmeticCalculator) Proxy.newProxyInstance(
//类加载器
target.getClass().getClassLoader(),
//被代理的接口
target.getClass().getInterfaces(),
//匿名内部类
new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//增加日志
System.out.println("The method "+ method.getName() + "begins with : " + Arrays.toString(args));
Object result = method.invoke(target,args);
System.out.println("The method "+ method.getName() + "ends with :" + result);
return result;
}
});
//调用被代理类的目标方法
proxy.add(5, 7);
proxy.sub(10, 5);
}
}
输出:The method addbegins with : [5, 7]
The method addends with :12
The method subbegins with : [10, 5]
The method subends with :5
越来越多的非业务需求(日志和验证)加入后,原有的计算器方法急剧膨胀。
每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点。以日志需求为例,
只是为了满足这个单一需求,就不得不在多个模块里多次重复相同的日志代码。
如果日志需求发生变化,必须修改所以模块。
关于动态代理的细节
1.需要一个被代理的对象。
2.类加载器通常是和被代理对象使用相同的类加载器。
3.一般地,Proxy.newInstance()的返回值是一个被代理对象实现的接口的类型。
当然也可以是其他的接口的类型
//被代理的接口
public interface ArithmeticCalculator {
public int add(int a, int b);
public int sub(int a, int b);
public int mul(int a, int b);
public int div(int a, int b);
}
//被代理的实现类
public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
@Override
public int add(int a, int b) {
return a + b;
}
@Override
public int sub(int a, int b) {
return a - b;
}
@Override
public int mul(int a, int b) {
return a * b;
}
@Override
public int div(int a, int b) {
return a / b;
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import org.junit.Test;
public class TestProxy {
@Test
public void testProxy(){
ArithmeticCalculator target = new ArithmeticCalculatorImpl();
//创建代理类
final ArithmeticCalculator proxy = (ArithmeticCalculator) Proxy.newProxyInstance(
//类加载器
target.getClass().getClassLoader(),
//被代理的接口
target.getClass().getInterfaces(),
//匿名内部类
new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//增加日志
System.out.println("The method "+ method.getName() + "begins with : " + Arrays.toString(args));
Object result = method.invoke(target,args);
System.out.println("The method "+ method.getName() + "ends with :" + result);
return result;
}
});
//调用被代理类的目标方法
proxy.add(5, 7);
proxy.sub(10, 5);
}
}
输出:The method addbegins with : [5, 7]
The method addends with :12
The method subbegins with : [10, 5]
The method subends with :5