java中代理模式
java中代理模式
前言
代理(Proxy)模式是一种结构型设计模式,提供了对目标对象另外的访问方式——即通过代理对象访问目标对象。
这样做的好处是:可以在目标对象实现的基础上,扩展目标对象的功能。
代理模式主要涉及三个角色:
Real Subject:目标类,也就是被代理类、委托类。用来真正完成业务服务功能;
Proxy:代理类,将自身的请求用 Real Subject 对应的功能来实现,代理类对象并不真正的去实现其业务功能;
Subject:定义 RealSubject 和 Proxy 角色都应该实现的接口。
正文
静态代理
静态代理需要先定义接口,被代理对象与代理对象一起实现相同的接口,代理类持有目标类的引用,然后通过调用相同的方法来调用目标对象的方法
代码实例:
接口类 CarInterfaces.class,定义一组接口
interface CarInterfaces {
void run();
}
目标类 Car.class
public class Car implements CarInterfaces {
@Override
public void run() {
System.out.println("Car run()");
}
}
代理类 CarSystemProxy.class
public class CarSystemProxy implements CarInterfaces {
Car car;
@Override
public void run() {
System.out.println("before car run");
if (car == null) {
car = new Car();
}
car.run();
System.out.println("after car run");
}
}
测试类 CarTest.class
public class CarTest {
public static void main(String[] args) {
CarSystemProxy carSystemProxy = new CarSystemProxy();
carSystemProxy.run();
}
}
问题:当目标类接口增多后,代理类要代理新增的接口,如果按照静态代理的模式,代理类中要同步新增接口,这时候就显得比较麻烦,怎么才能优化这个操作呢?
动态代理
拓展接口如下 CarInterfaces.class:
interface CarInterfaces {
void run();
void playMusic();
void stop();
}
目标类实现接口 Car.class:
public class Car implements CarInterfaces {
@Override
public void run() {
System.out.println("Car run()");
}
@Override
public void playMusic() {
System.out.println("Car playMusic()");
}
@Override
public void stop() {
System.out.println("stop()");
}
}
代理类 动态代理接口 CarSystemProxy.class:
public class CarSystemProxy {
Car car;
public Object getProxy() {
if (car == null) {
car = new Car();
}
return Proxy
.newProxyInstance(getClass().getClassLoader(), car.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("find proxy.... ");
Object invoke = method.invoke(car, args);
return invoke;
}
});
}
}
测试类 CarTest.class:
public class CarTest {
public static void main(String[] args) {
CarSystemProxy carSystemProxy = new CarSystemProxy();
CarInterfaces proxy = (CarInterfaces) carSystemProxy.getProxy();
proxy.run();
proxy.playMusic();
proxy.stop();
}
}