Java基础 (15) 代理模式
2019-02-20 本文已影响0人
perry_Fan
问题1. 静态代理的使用方式和场景
问题2. 动态代理如何实现和场景
一. 静态代理
静态代理的实现模式一般是:首先创建一个接口,然后创建具体实现类来实现这个接口,然后再创建一个代理类同样实现这个接口。
举例:
1)抽象主题(接口)
public interface Movie {
void play();
}
2)被代理角色(目标类)与代理角色(代理类)
public class RealMovie implements Movie {
@Override
public void play() {
// TODO Auto-generated method stub
System.out.println("您正在观看电影 《肖申克的救赎》");
}
}
public class Cinema implements Movie {
RealMovie movie;
public Cinema(RealMovie movie) {
super();
this.movie = movie;
}
@Override
public void play() {
guanggao(true); // 代理类的增强处理
movie.play(); // 代理类把具体业务委托给目标类,并没有直接实现
guanggao(false); // 代理类的增强处理
}
public void guanggao(boolean isStart){
if ( isStart ) {
System.out.println("电影马上开始了,爆米花、可乐、口香糖9.8折,快来买啊!");
} else {
System.out.println("电影马上结束了,爆米花、可乐、口香糖9.8折,买回家吃吧!");
}
}
}
3)客户端
package com.frank.test;
public class ProxyTest {
public static void main(String[] args) {
RealMovie realmovie = new RealMovie();
Movie movie = new Cinema(realmovie);
movie.play();
}
}
二. 动态代理
1)抽象主题(接口)
public interface Subject {
public void doSomething();
}
2)被代理角色(目标类)
public class RealSubject implements Subject {
public void doSomething() {
System.out.println("call doSomething()");
}
}
3)代理角色(代理类)与客户端
在动态代理中,代理类及其实例是程序自动生成的,因此我们不需要手动去创建代理类。在Java的动态代理机制中,InvocationHandler(Interface)接口和Proxy(Class)类是实现我们动态代理所必须用到的。事实上,Proxy通过使用InvocationHandler对象生成具体的代理代理对象,下面我们看一下对InvocationHandler接口的实现:
public class ProxyHandler implements InvocationHandler {
private Object proxied; // 被代理对象
public ProxyHandler(Object proxied) {
this.proxied = proxied;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 在转调具体目标对象之前,可以执行一些功能处理
System.out.println("前置增强处理: yoyoyo...");
// 转调具体目标对象的方法(三要素:实例对象 + 实例方法 + 实例方法的参数)
Object obj = method.invoke(proxied, args);
// 在转调具体目标对象之后,可以执行一些功能处理
System.out.println("后置增强处理:hahaha...");
return obj;
}
}
在实现了InvocationHandler接口后,我们就可以创建代理对象了。在Java的动态代理机制中,我们使用Proxy类的静态方法newProxyInstance创建代理对象,如下:
public class Test {
public static void main(String args[]) {
// 真实对象real
Subject real = new RealSubject();
// 生成real的代理对象
Subject proxySubject = (Subject) Proxy.newProxyInstance(
Subject.class.getClassLoader(), new Class[] { Subject.class },
new ProxyHandler(real));
proxySubject.doSomething();
System.out.println("代理对象的类型 : " + proxySubject.getClass().getName());
System.out.println("代理对象所在类的父类型 : " + proxySubject.getClass().getGenericSuperclass());
}
}/** Output
前置增强处理: yoyoyo...
call doSomething()
后置增强处理:hahaha...
代理对象的类型 : com.sun.proxy.$Proxy0
代理对象所在类的父类型 : class java.lang.reflect.Proxy
**/
静态:由程序员创建代理类或特定工具自动生成源代码再对其编译。在程序运行前代理类的.class文件就已经存在了。
动态:在程序运行时运用反射机制动态创建而成。