1、静态代理
/**抽象对象:声明了真实对象和代理对象的公共方法(男性情趣用品公司接口)*/
public interface Subject {
void saleTt();
}
/**真实对象:代理对象所代表的真实对象,最终被引用的对象(A情趣用品公司)*/
public class RealSubject implements Subject {
public void saleTt() {
//....真实对象的处理方法
}
}
/**代理对象:包含真实对象从而操作真实主题对象,相当于访问者和真实对象直接的中介(个人代购)*/
public class Proxy implements Subject {
private Subject subject;
public Proxy(Subject subject) {
this.subject = subject;
}
public void saleTt() {
doBefore();//前置增强
subject.saleTt();//真实对象的业务处理
doAfter();//后置增强
}
}
/**访问者:通过代理对象访问目标对象的方法(张三)*/
public class Client {
public static void main(String[] args) {
Subject subject = new RealSubject();
Proxy proxy = new Proxy(subject);
proxy.saleTt();
}
}
静态代理使用代理类中的入参为真实对象的构造方法生成代理类,通过代理类的方法 去调用真实对象的方法;与特定的真实对象耦合,如果有新的需求,需要修改代理类 来实现。
- 不足之处: 扩展性差,可维护性差;
2、动态代理
/**抽象对象:声明了真实对象和代理对象的公共接口(公司接口)*/
public interface ManToolsCompany {
void saleManTool(String size);
}
/**真实对象:代理对象所代表的真实对象,最终被引用的对象(A公司,B公司)*/
public class AaCompany implements ManToolsCompany {
@Override
public void saleManTool(String size) {
//...真实对象的业务处理
}
}
/**代理对象:包含真实对象从而操作真实主题对象,相当于访问者和真实对象直接的中介(海外代购公司)*/
public class LisonCompany implements InvocationHandler {
//代理对象
private Object compy;
/**标注服务流程*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
doSomeThingBefore();//前置增强
Object invoke = method.invoke(compy, args);//反射调用代购公司业务处理方法
doSomeThingEnd();//后置增强
return invoke;
}
//获取代理示例
public Object getProxyInstance(){
return Proxy.newProxyInstance(compy.getClass().getClassLoader(), compy.getClass().getInterfaces(), this);
}
}
/**访问者:通过代理对象访问目标对象的方法(张三,张三媳妇)*/
public class Client {
public static void main(String[] args) {
//真实对象
ManToolsCompany aacomp = new AaCompany();
WomanToolsCompany bbcomp = new BbCompany();
//代理对象
LisonCompany lisonCompany = new LisonCompany();
lisonCompany.setCompy(aacomp);
ManToolsCompany lison1 = (ManToolsCompany) lisonCompany.getProxyInstance();
lison1.saleManTool("C");
lisonCompany.setCompy(bbcomp);
WomanToolsCompany lison2 = (WomanToolsCompany) lisonCompany.getProxyInstance();
lison2.saleWomanTool(1.8f);
ProxyUtils.generateClassFile(ManToolsCompany.class, lison1.getClass().getName());
ProxyUtils.generateClassFile(WomanToolsCompany.class, lison2.getClass().getName());
}
}
动态代理的代理类实现特定InvocationHandler接口, 在类中使用Object类型的变量, 任何真实对象都可以传入,使用Proxy的静态方法newProxyInstance方法根据 传入Object类的类的相关信息(类加载器、实现的接口、当前对象)来生成真实对象的实例, 重写invoke方法,在invoke方法中调用真实对象的业务方法,在调用方法前后进行增强处理。 在通过代理类生成的真实对象的方法被调用时,调用了代理类中的重写的invoke方法,实现功能。
- 动态代理的优点: 不与特定的真实对象耦合,业务修改只需要增加新的真实对象,代理类不用修改。
JDK动态代理
Proxy:有资源的海外代购人(全职、兼职),调度中心,使用静态方法Proxy.newProxyInstance生成真实对象
InvocationHandler:优质的代购服务,提供标准服务,在invoke方法之前之后可以进行增强
类的完整生命周期
Java源文件(Java文件)–编译–>Java字节码(.class文件)–类加载–>Class对象–实例化–>实例对象—->卸载
.java源文件通过javac命令编译为.class字节码文件,通过类加载器ClassLoader加载全类名的.class文件在JVM中生成Class对象, 在new的时候通过Class对象实例化出对象实例进行使用,垃圾回收时实例对象的可达性分析与根节点没有关联时jvm卸载对象。