基本类:加减乘除日志打印练习
package reflect.proxy;
public interface ArithmeticCalculator {
public int add(int i,int j);
public int sub(int i,int j);
public void mul(int i,int j);
public void div(int i,int j);
}
package reflect.proxy;
public class ArithmeticCalculaterImpl implements ArithmeticCalculator{
@Override
public int add(int i, int j) {
return i+j;
}
@Override
public int sub(int i, int j) {
int result=i-j;
return result;
}
@Override
public void mul(int i, int j) {
int result=i*j;
System.out.println(result);
}
@Override
public void div(int i, int j) {
int result=i/j;
}
}
测试使用总结
方式1:
package reflect.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import org.junit.Test;
/**
* 动态代理
* @author yabushan
*
*/
public class ProxyTest {
/**
* 关于动态代理的细节
* 1.需要一个被代理的对象
* 2.一般地,proxy.newInstance()的返回值一定是一个被代理对象实现的接口的类型
* 当然也可以是其他的接口的类型
* 3.类加载器通常是和被代理对象使用相同的类加载器
* 提示:若代理对象不需要额外实现被代理对象实现的接口以外的接口,可以使用:
* target
* .getClass().getInterfaces()
* 4.InvocationHandler 通常使用匿名内部类的方式.
* 被代理对象必须是final类型:final 使得被代理对象能有较长的生命周期
* 5.InvocationHandler的invoke()方法中的第一个参数object
* 类型的proxy指的是正在被返回的那个代理对象一般情况下不使用(避免死循环执行invoke()方法)
*/
@Test
public void testProxy2(){
final ArithmeticCalculator target = new ArithmeticCalculaterImpl();
ArithmeticCalculator proxy= (ArithmeticCalculator) Proxy.newProxyInstance(target.getClass().getClassLoader(),
//new Class[]{ArithmeticCalculator.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);
}
});
proxy.add(3, 4);
}
@Test
public void testProxy(){
/**
* ClassLoader:由动态代理产生的对象由哪个类加载器来加载
* 通常情况下和被代理对象使用一样的类加载器
* Class<?>[]:由动态代理产生的对象必须需要实现的接口的class数组
* InvocationHandler:当具体调用代理对象的方法时,将产生什么行为。
*/
final ArithmeticCalculator arithmeticCalculator=new ArithmeticCalculaterImpl();
ArithmeticCalculator proxy=(ArithmeticCalculator) Proxy.newProxyInstance(arithmeticCalculator.getClass().getClassLoader(),
new Class[]{ArithmeticCalculator.class},
new InvocationHandler() {
/**
* proxy:
* method:正在被调用的方法
* args:调用方法时传入的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// System.out.println("invoke...");
// System.out.println("method:"+method);
// System.out.println("args:"+Arrays.asList(args));
System.out.println("the method"+method.getName()+"begin"+Arrays.asList(args));
//调用被代理类的目标方法
Object result =method.invoke(arithmeticCalculator, args);
System.out.println("the method"+method.getName()+"end"+"result:"+result);
return result;
}
});
proxy.mul(3, 8);
int result=proxy.add(3, 4);
System.out.println(result);
}
}
方式2
package aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
public class arithmeticCalculatorLogginProxy {
//要代理的对象
private ArithmeticCalculator target;
public arithmeticCalculatorLogginProxy(ArithmeticCalculator tCalculator){
this.target=tCalculator;
}
public ArithmeticCalculator getLogginProxy() {
ArithmeticCalculator proxy=null;
//代理对象由哪个类加载器负载加载
ClassLoader loader=target.getClass().getClassLoader();
//代理对象的类型,即其中有哪些方法
Class[] interfaces =new Class[]{ArithmeticCalculator.class};
//当调用代理对象其中的方法时,该执行的代码
InvocationHandler h =new InvocationHandler() {
/**
* proxy:正在返回的那个代理对象,一般情况下,在invoke方法中都不使用该对象
* method:正在被调用的方法
* args:调用方法时,传入的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("invoke..");
String methodName=method.getName();
//日志
System.out.println("the method"+methodName+"begin with:"+Arrays.asList(args));
return method.invoke(target, args);
}
};
proxy=(ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h);
return proxy;
}
}
package aop;
public class test {
public static void main(String[] args) {
ArithmeticCalculator target=new ArithmeticCalculaterImpl();
ArithmeticCalculator proxy = new arithmeticCalculatorLogginProxy(target).getLogginProxy();
int result1= proxy.add(1, 3);
System.out.println(result1);
}
}