代理类和被代理类有一个共同的接口,被代理类实现了接口的抽象方法,代理类调用了被代理类的方法,并加入了自己的方法。在main函数中创建代理类对象并调用即可。
缺点:请求速度变慢
作用:进行访问控制、远程通信、日志、缓存
场景:远程代理
/*
真实类:代理类调用的类。事先不知道这个,用动态代理
*/
public class RealSubject implements Subject {
@Override
public void buyMAC() {
System.out.println("buy MAC");
}
}
/*
代理类:包含对象的引用,从而调用真实对象。两者方法名相同,从而任何时刻可以代替真实对象。
*/
public class Proxy implements Subject{
@Override
public void buyMAC() {
//引用并创建真实对象实例,即”我“
RealSubject realSubject = new RealSubject();
//调用真实对象的方法,进行代理购买Mac
realSubject.buyMAC();
//代理对象额外做的操作
this.WrapMac();
}
public void WrapMac(){
System.out.println("用盒子包装好Mac");
}
}
/*
抽象类:真是对象和代理对象的共同接口
*/
public interface Subject {
public void buyMAC();
}
public class Main {
public static void main(String[] args) {
Subject proxy = new Proxy();
proxy.buyMAC();
}
}
输出
buy MAC
用盒子包装好Mac
/*
参考http://www.cnblogs.com/xiaoluo501395377/p/3383130.html
*/
interface Subject{
void action();
void action2();
}
//被代理类,被代理的真实对象
class RealSubject implements Subject{
@Override
public void action() {
System.out.println("buy MAC");
}
@Override
public void action2() {
System.out.println("bue MAC2");
}
}
//动态代理类,InvocationHandler对象
class MyInvocationHandler implements InvocationHandler{
Object obj;
//传入被代理类。
public MyInvocationHandler(Object object) {
this.obj = object;
}
//代理类对象调用代理方法时,这个方法自动被调用
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("这就是面向切面编程");
//看看method是什么
System.out.println("Method:" + method);
//当代理对象调用真实对象的方法时,其会自动地跳转到代理对象关联的handler对象的invoke方法来进行调用
Object returnVal = method.invoke(obj, args);
System.out.println("包装MAC");
return returnVal;
}
}
public class DynamicProxy {
public static void main(String[] args) {
// 我们要代理的真实对象
RealSubject real = new RealSubject();
// 我们要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法的
MyInvocationHandler handler = new MyInvocationHandler(real);
//返回动态代理对象。第一个参数real和handler都可以
// ①让动态代理对象继承接口(第二个参数)②动态代理对象调用方法的时候,会关联到InvocationHandler的对象上
Object obj = Proxy.newProxyInstance(real.getClass().getClassLoader(),
real.getClass().getInterfaces(),
handler);
System.out.println(obj.getClass().getName()); //输出的类名说明,它是运行时动态生成的对象
Subject sub = (Subject)obj; //因为编译看左边,obj直接调用action()会失败。
sub.action();
sub.action2();
}
}