三种代理方式
静态代理模式
1.客户端
public class Client {
public static void main(String[] args){
Subject subject = new Proxy(new RealSubject());
subject.request(); }}
2.代理接口
public interface Subject {
public void request();
}
3.代理类
public class Proxy implements Subject{ //引入目标对象
private RealSubject realSubject;
public Proxy(RealSubject realSubject) {
this.realSubject = realSubject;
}
public void request(){
System.out.println("开始....");
realSubject.request();
System.out.println("结束。。。。");
}}
4.目标类
public class RealSubject implements Subject{
public void request(){
System.out.println("目标对象。。。。");
}}
动态代理模式 基于JDK代理 InvocationHandler代理接口
1.客户端
public class Client {
public static void main(String[] args){ //动态代理对象进行调用
Subject subject = (Subject) Proxy.newProxyInstance(Client.class.getClassLoader(),new Class[] {Subject.class},new JdkProxySubject(new RealSubject()));
}
}
2.代理类
public class JdkProxySubject implements InvocationHandler{
private RealSubject realSubject; //目标对象
public JdkProxySubject(RealSubject realSubject) {
this.realSubject = realSubject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before");
Object result = null;
try{
result = method.invoke(realSubject,args); //调用目标对象的方法
}catch (Exception e){
System.out.println("ex:"+e.getMessage());
throw e;
}finally {
System.out.println("after");
}
return result;}}
源码解读
客户端调用
public static void main(String[] args){
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
//动态代理对象进行调用
Subject subject = (Subject) Proxy.newProxyInstance(Client.class.getClassLoader(),new Class[] {Subject.class}, new JdkProxySubject(new RealSubject()));
// subject.hello();
}
在proxy类中
//该方法中主要从缓存中拿类,如果存在直接从缓存中取,否则创建并放入缓存中
Class cl = getProxyClass0(loader, intfs);
//主要ProxyClassFactory 类中生成
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
interfaceClass = Class.forName(intf.getName(), false, loader); //读取接口信息
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags); //通过生成器生成字节码文件
网友评论