1. 类图
- Proxy:代理对象
- Subject:目标接口
- RealSubject:具体的目标对象
2. 示例
2.1 静态代理
代理对象持有真实对象的引用,代理类和真实类实现共同的接口
2.1.1 目标接口
public interface Movie {
void play();
}
2.1.2 目标对象
public class RealMovie implements Movie {
public void play() {System.out.println("观看电影《当幸福来敲门》");}
}
2.1.3 代理对象
public class ProxyMovie implements Movie {
// 持有真实对象的引用
RealMovie realMovie;
public ProxyMovie(RealMovie realMovie) {
this.realMovie = realMovie;
}
@Override
public void play() {
slogan(true);
realMovie.play();
slogan(false);
}
private void slogan(boolean isStart) {
if (isStart) {
System.out.println("电影即将开始,请关闭手机");
} else {
System.out.println("电影即将结束,请有序离场");
}
}
}
2.1.4 客户端
public class Client {
public static void main(String[] args) {
RealMovie realMovie = new RealMovie();
ProxyMovie proxyMovie = new ProxyMovie(realMovie);
proxyMovie.play();
}
}
2.2 JDK动态代理
2.2.1 目标接口
public interface Movie {
void play();
}
2.2.2 目标对象
public class RealMovie implements Movie {
@Override
public void play() {
System.out.println("观看电影《幸福来敲门》");
}
}
2.2.3 代理对象
public class ProxyMovie<T extends Movie> implements InvocationHandler {
T t;
public T getInstance(T t) {
this.t = t;
return (T) Proxy.newProxyInstance(
t.getClass().getClassLoader(),
t.getClass().getInterfaces(),
this);
}
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
System.out.println("电影即将开始,请关闭手机");
method.invoke(t, objects);
System.out.println("电影即将结束,请有序离场");
return null;
}
}
2.2.4 客户端
public class Client {
public static void main(String[] args) {
ProxyMovie<Movie> movieProxyMovie = new ProxyMovie<>();
Movie instance = movieProxyMovie.getInstance(new RealMovie());
instance.play();
}
}
2.3 CGLIB动态代理
目标对象必须能够被继承
2.3.1 所需jar包
2.3.2 目标对象
public class RealMovie {
public void play() {System.out.println("观看电影《当幸福来敲门》");}
}
2.3.3 代理对象
public class ProxyMovie<T> implements MethodInterceptor {
T t;
public T getInstance(T t){
this.t = t;
// 创建动态代理类
Enhancer enhancer = new Enhancer();
// 设置父类
enhancer.setSuperclass(t.getClass());
// 设置回调
enhancer.setCallback(this);
return (T) enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("CGLIB动态代理:电影即将开始,请关闭手机");
method.invoke(t, objects);
System.out.println("CGLIB动态代理:电影即将结束,请有序离场");
return null;
}
}
2.3.4 客户端
public class Client {
public static void main(String[] args) {
ProxyMovie<Object> objectProxyMovie = new ProxyMovie<>();
RealMovie instance = (RealMovie) objectProxyMovie.getInstance(new RealMovie());
instance.play();
}
}