动态代理
废话不多数,直接上干货
- 这是接口的代码
public interface Car {
public void start();
public void run();
public void stop();
public String test(int a,int b);
}
- 这是实现类的代码
public final class GoogleCar implements Car {
@Override
public void start() {
System.out.println("start...");
}
@Override
public void run() {
System.out.println("run...");
}
@Override
public void stop() {
System.out.println("stop...");
}
@Override
public String test(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;
public class Test {
public static void main(String[] args) {
// 参数一:当前类的加载器
// 参数二:代理的类的接口的方法总数
// 参数三:解决方案
// 返回值:代理的类的接口类实现类的的实例
Car car = (Car)Proxy.newProxyInstance(Test.class.getClassLoader(), GoogleCar.class.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// System.out.println(proxy.getClass().getName()); //不知道有什么用
// System.out.println(method.getName()); //获取当前方法
// System.out.println(Arrays.deepToString(args)); //方法的参数
Object obj = null;
obj = method.invoke(new GoogleCar(), args);//执行该方法 并接受返回值 如果有的话
return obj; //返回值 如果有的话
}
});
car.start();
car.run();
car.stop();
String s = car.test(10, 30);
System.out.println(s);
}
}
- 动态增强某个方法
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Test2 {
public static void main(String[] args) {
Car c =(Car)Proxy.newProxyInstance(Test2.class.getClassLoader(), GoogleCar.class.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object obj = null;
if(method.getName().equalsIgnoreCase("test")) {//找到需要增强的方法
System.out.println("参数1--->"+args[0]);
System.out.println("参数2--->"+args[1]);
obj = method.invoke(new GoogleCar(), args);
}else {
obj = method.invoke(new GoogleCar(), args);
}
return obj;
}
});
c.start();
c.run();
c.stop();
String s = c.test(10, 20);
System.out.println(s);
}
}
总结
使用动态代理可以很好解决装饰者模式下的冗余代码的弊端
需要增强那个方法只要指定那个方法,不需要重写其他不需要改变的代码