静态代理
interface play{void game(String name);void music();}class someone implements play{@Overridepublic void game(String name) {System.out.println("玩游戏");}@Overridepublic void music() {System.out.println("听音乐");}}class Proxyer implements play{private play player;public Proxyer(play player){this.player = player;}@Overridepublic void game(String name) {System.out.println("代理人玩游戏---"+name);player.game("p");}@Overridepublic void music() {System.out.println("代理人听音乐---");player.music();}}public class Main {public static void consumers(play p){p.game("s");p.music();}public static void main(String[] args) {consumers(new someone());consumers(new Proxyer(new someone()));// someone player = new someone();// Proxyer proxyer = new Proxyer(player);// proxyer.game();// proxyer.music();}}代理人玩游戏---s玩游戏代理人听音乐---听音乐
动态代理
class ProxyHandler<T> implements InvocationHandler {private T proxy;public ProxyHandler(T proxy){this.proxy = proxy;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("代理人执行:" + method.getName() + "(), args: "+ Arrays.toString(args));return method.invoke(this.proxy,args);//要调用method方法名 proxied真正调用方法的实例 args要传入方法的参数}}public class DyProxy {public static void main(String[] args) {play one = new someone();play o = (play) Proxy.newProxyInstance(someone.class.getClassLoader(),someone.class.getInterfaces(),new ProxyHandler<>(one));o.music();o.game("荒野大镖客");}}
public class MainTest {public static void main(String[] args) {InvocationHandler handler = new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(method.getName());if (method.getName().equals("morning")) {System.out.println("Good morning, " + Arrays.toString(args));}return null;}};Object o = Proxy.newProxyInstance(Hello.class.getClassLoader(), // 传入ClassLoadernew Class[]{Hello.class}, // 传入要实现的接口handler);// 传入处理调用方法的InvocationHandler((Hello)o).morning("Bob",4);}}interface Hello {void morning(String name, int age);}//morning//Good morning, [Bob, 4]
在运行期动态创建一个interface实例的方法如下:
- 定义一个InvocationHandler实例,它负责实现接口的方法调用;
- 通过Proxy.newProxyInstance()创建interface实例,它需要3个参数:
- 使用的ClassLoader,通常就是接口类的ClassLoader;
- 需要实现的接口数组,至少需要传入一个接口进去;
- 用来处理接口方法调用的InvocationHandler实例。
- 将返回的Object强制转型为接口。
没有实现类,只用接口实现动态代理
public interface UserMapper {int add(int a ,int b);static void main(String[] args) {final UserMapper proxyInstance = (UserMapper) Proxy.newProxyInstance(UserMapper.class.getClassLoader(), new Class[]{UserMapper.class},new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(method.getDeclaringClass());if (Object.class.equals(method.getDeclaringClass())) { //编程技巧,永远不会走if里面return method.invoke(this, "加运算执行");} else {int add = (int)args[0]+(int)args[1] ;return add ;}}});System.out.println(proxyInstance.add(3, 4));}}
