静态代理
现在有一个接口IUser
1 2 3 4 5
| public interface IUser { void show(); }
|
UserImpl类实现了IUser接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class UserImpl implements IUser{ public UserImpl(){
} @Override public void show() { System.out.println("调用show()"); }
}
|
下面是代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class UserProxy implements IUser{ IUser user; public UserProxy(){ } public UserProxy(IUser user){ this.user=user; } @Override public void show(){ user.show(); System.out.println("代理调用了show()"); } }
|
下面主函数简单运行一下
1 2 3 4 5 6 7
| public class ProxyTest { public static void main(String[] args) { IUser user = new UserImpl(); IUser userProxy = new UserProxy(user); userProxy.show(); } }
|
会发现输出了:
调用show()
代理调用了show
这就是静态代理,在这种情况下,同一个接口的每个函数都要有相对应的代理实现,在这里是show方法的代理,如果一个接口还有delete方法、insert方法等等呢,每个方法都要写一个代理方法吗?显然太麻烦了,所以有了动态代理。
动态代理
现在取消IUser接口和UserImpl类的注释,写一个UserInvocationHandler类,即动代理中 中介的角色
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method;
public class UserInvocationHandler implements InvocationHandler { IUser user; public UserInvocationHandler(){} public UserInvocationHandler(IUser user) { this.user=user; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{ method.invoke(user,args); return null; } }
|
注:中介类必须要实现InvocationHandler接口
主函数采用如下写法:
1 2 3 4 5 6 7 8
| public class ProxyTest { public static void main(String[] args) { IUser user = new UserImpl(); InvocationHandler userinvocationhandler = new UserInvocationHandler(user); IUser userProxy=(IUser)Proxy.newProxyInstance(user.getClass().getClassLoader(), user.getClass().getInterfaces(),userinvocationhandler); userProxy.show(); }
|
主函数第二行代码创建了 UserInvocationHandler 的实例 userinvocationhandler,并将之前创建的 user 传递给它。这样UserInvocationHandler 可以在方法被调用时对 user 进行操作。
第三行将创建的代理对象赋给 IUser userProxy,此时 userProxy 是一个可以调用 IUser 接口方法的代理对象,第三个参数是 InvocationHandler 实例 userinvocationhandler,用于处理对代理对象的方法调用。
在借助代理对象调用具体的方法时,show在此处作为method传递到invoke方法中,args在这里为空,method.invoke(user, args)实际上执行了 user 的 show() 方法
到这就很清晰了,如果要调用delete、insert方法,只需要改userProxy.xxxxx就行了
参考
https://www.bilibili.com/video/BV16h411z7o9?p=3&vd_source=9fe5dd16d67801322fd30df51f7b3fd8
Java 静态代理&动态代理学习 – 天下大木头 (wjlshare.com)
GPT