•
Proxy
提供用于创建动态代理类和代理对象的静态方法
,
它也是所有动态代理类的父类
.
•
Proxy
提供了两个方法来创建动态代理类和动态代理实例
使用动态代理实现 AOP
•
AOP(Aspect
OrientProgram,
面向切面编程
)
public class ProxyTest {
@Test
public void testProxy() {
final IArithmeticCalculator arithmeticCalculator = new ArithemeticCalculatorImpl();
/**
* Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
*
* ClassLoader: 由动态代理产生的对象由哪个类加载器来加载,通常情况下和被代理对象使用一样的类加载器
* Class<?>[]: 由动态代理产生的对象必须需要实现的接口的Class 数组
* InvocationHandler: 当具体调用代理对象的方法时,将产生什么行为
*/
IArithmeticCalculator proxy1 =
(IArithmeticCalculator) Proxy.newProxyInstance(
arithmeticCalculator.getClass().getClassLoader(),
new Class[]{IArithmeticCalculator.class},
new InvocationHandler() {
/**
* @param proxy
* @param method 正在被调用的方法
* @param args 调用方法时传入的参数
* Arrays.asList()将一个数组转化为一个List对象,这个方法会返回一个ArrayList类型的对象,
这个ArrayList类并非java.util.ArrayList类,而是Arrays类的静态内部类!
用这个对象对列表进行添加删除更新操作,就会报UnsupportedOperationException异常。
*/
// @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("The method " + method.getName() + " begins with " + Arrays.asList(args));
//调用被代理类的目标方法
Object result = method.invoke(arithmeticCalculator, args);
System.out.println("The method " + method.getName() + " ends with " + result);
return result;
}
});
proxy1.mul(1, 2); //he method mul ends with null 原因是Mul没有返回值
// int result = proxy1.add(2, 5);
// System.out.println(result);
}
/**
* 关于动态代理的细节
* 1、需要一个被代理的对象
* 2、类加载器通常是和被代理对象使用相同的类加载器
* 3、一般的,Proxy.newInstance()的返回值是一个被代理对象实现的接口的类型;当然也可以是其它的接口的类型
* 注意:第二个参数,必须是一个接口类型的数组
* 提示:若代理对象不需要额外实现被代理对象实现的接口以外的接口,可以使用target.getClass().getInterfaces(),
*
* 4、InvocationHandler通常使用匿名内部类的方式:被代理对象需要是final类型的,定义常量,可能方法实现完了,但对象还在被使用
* 5、InvocationHandler的invoke方法中的第一个参数Object类型的proxy
* 指的是正下被返回的那个代理对象,一般情况下不使用
*/
@Test
public void testProxy2() {
//1、创建一个被代理的对象
final IArithmeticCalculator target = new ArithemeticCalculatorImpl();
System.out.println(Arrays.asList(target.getClass().getInterfaces())); //[interface com.changwen.java.dynamicProxy.IArithmeticCalculator]
Object proxy1 = Proxy.newProxyInstance(
target.getClass().getClassLoader(),
// new Class[]{IArithmeticCalculator.class, Validator.class},
target.getClass().getInterfaces(),
new InvocationHandler() {
// @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(target,args);
}
});
IArithmeticCalculator proxy2 = (IArithmeticCalculator) proxy1;
proxy2.mul(5, 2);
}
}