核心作用
通过代理,控制对对象的访问。
可以详细控制某个(某类)对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理(AOP面向切面的微观实现),从而将统一流程放到代理类中处理。
核心角色
抽象角色:定义代理角色和真实角色的公共对外方法。
真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色使用。
代理角色:实现抽象角色,是真实角色的代理(即,持有对真实角色的引用),通过真实角色的业务逻辑来实现抽象方法,可以附加自己的操作。
分类
静态代理:静态定义代理类
动态代理:动态生成代理类
静态代理的实现
以明星唱歌为例,假设流程如下:面谈——签合同——订票——唱歌(明星本人)——收款
1.定义抽象角色
package Proxy.staticProxy;
/**
* 抽象角色:定义代理角色和真实角色的公共对外方法
* @author baka
*
*/
public interface Star {
/**
* 面谈
*/
public void confer();
/**
* 签合同
*/
public void signContract();
/**
* 订票
*/
public void bookTicket();
/**
* 唱歌
*/
public void sing();
/**
* 收款
*/
public void collectMoney();
}
2.定义真实角色
真实角色真正要做的事情就是唱歌
package Proxy.staticProxy;
/**
* 真实角色
* 实现抽象角色,定义真实角色所要实现的业务逻辑
* @author baka
*
*/
public class RealStar implements Star{
@Override
public void confer() {
}
@Override
public void signContract() {
}
@Override
public void bookTicket() {
}
@Override
public void sing() {
System.out.println("真实角色:明星本人唱歌!");
}
@Override
public void collectMoney() {
}
}
3.定义代理角色
package Proxy.staticProxy;
/**
* 代理角色
* 实现抽象角色,并且持有真实角色的引用
* 处理统一的控制流程
* @author baka
*
*/
public class ProxyStar implements Star{
private Star star;
public ProxyStar(Star star) {
super();
this.star = star;
}
@Override
public void confer() {
System.out.println("代理角色:面谈");
}
@Override
public void signContract() {
System.out.println("代理角色:签合同");
}
@Override
public void bookTicket() {
System.out.println("代理角色:订票");
}
/**
* 唱歌只能由真实角色来做
*/
@Override
public void sing() {
star.sing();
}
@Override
public void collectMoney() {
System.out.println("代理角色:收尾款");
}
}
4.测试
public class Client {
public static void main(String[] args) {
Star real = new RealStar();
//代理角色持有真实对象的引用
Star proxy = new ProxyStar(real);
proxy.confer();
proxy.signContract();
proxy.sing();
proxy.collectMoney();
}
}
5.运行结果
我们可以看到,只有唱歌是由明星本人做的,其他事情都是代理角色做的,由此,就实现了静态代理。
动态代理
两个重要的类
import java.lang.reflect.Proxy;
动态生成代理类和对象
import java.lang.reflect.InvocationHandler;(处理器接口)
可以通过invoke方法实现对真实角色的代理访问
每次通过Proxy生成代理类对象时都要指定对应的处理器接口
1.抽象角色和真实角色与上面的相同
2.处理器
package Proxy.dynamicProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 处理器
* @author baka
*
*/
public class StarHandler implements InvocationHandler{
Star realStar;
public StarHandler(Star realStar) {
this.realStar = realStar;
}
/**
* 统一流程控制
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object object = null;
System.out.println("真正的方法的执行前---->");
System.out.println("面谈");
System.out.println("签合同");
if (method.getName().equals("sing")) {
object = method.invoke(realStar, args);
}
System.out.println("真正的方法的执行后---->");
System.out.println("收尾款");
return object;
}
}
3.测试
package Proxy.dynamicProxy;
import java.lang.reflect.Proxy;
public class Client {
public static void main(String[] args) {
//真实对象
Star realStar = new RealStar();
//处理器对象
StarHandler handler = new StarHandler(realStar);
//代理对象,需指定对应的处理器对象
Star proxy = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
new Class[] {Star.class}, handler);
proxy.sing();
}
}
4.结果
我们可以看出,唱歌还是明星本人,那么其他操作就可以调用其他方法实现。