您的位置:首页 > 其它

代理模式

2016-03-17 19:50 204 查看
Provide a surrogate or placeholder for another object to control access to it.

代理模式的通用类图



代理模式的通用源码

抽象主题类(接口)

public interface Subject {
// 定义一个方法
public void request();
}


真实主题类

public class RealSubject implements Subject {

@Override
public void request() {
// 业务逻辑处理
System.out.println("HelloWorld");
}
}


代理类

public class Proxy implements Subject {
//要代理哪个实现类
private Subject subject = null;

// 默认被代理者
public Proxy(Subject _subject) {
this.subject = _subject;
}

// 通过构造函数传递代理者
public Proxy(Object ... objects) {

}

//实现接口中的方法
@Override
public void request() {
this.before();
this.subject.request();
this.after();
}

// 预处理
private void before() {
//do Something
}

// 善后处理
private void after() {
//do Something
}
}


场景类

public class Client {

public static void main(String[] args) {

Subject realSubject = new RealSubject();
Subject proxy = new Proxy(realSubject);
proxy.request();
}
}


代理模式的优点

职责清晰。真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件事务,附带的结果就是编程简洁清晰。

搞扩展性。具体的角色随时都会发生变化的,只要他实现了接口,都可以通过代理类不做任何的修改的情况下使用。

智能化。Struts是如何把表单映射到表单的。

代理模式的使用场景

打官司为什么要找律师?不想参与中间过程的是是非非,只要完成自己的答辩就成了,其他的如事前调查、时候追查都由律师搞定,目的就是要减轻自己的负担。

Spring AOP

代理模式的扩展应用

普通代理

强制代理 (从真是角色查找代理角色)

代理是有个性的 (代理角色还可以实现其他的接口)

动态代理

动态代理

动态代理1类图及源码



游戏者接口

public interface IGamePlayer {
//登录
public void login(String user, String password);
//杀怪
public void killBoss();
//升级
public void upgrade();
}


动态代理者类

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
* 动态代理者类
* @author hsx
*
*/
public class GamePlayerDynamic implements InvocationHandler  {

// 被代理的实例
Object object = null;
// 我要代理谁
public GamePlayerDynamic(Object _object) {
this.object = _object;
}

//调用被代理的方法
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = method.invoke(this.object, args);
if (method.getName().equalsIgnoreCase("login")) {
System.out.println("有人登录了我的账号");
}
return result;
}
}


真实游戏者类

public class GamePlayer implements IGamePlayer {

private String name = "";

public GamePlayer(String _name) {
this.name = _name;
}

@Override
public void login(String user, String password) {
System.out.println("登录名" + user + "的用户" + this.name + "登录成功!");
}

@Override
public void killBoss() {
System.out.println(this.name + "正在杀怪");
}

@Override
public void upgrade() {
System.out.println(this.name + "又升了一级");
}
}


场景类

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Client {

public static void main(String[] args) {

IGamePlayer gamePlayer = new GamePlayer("张三");
InvocationHandler handler = new GamePlayerDynamic(gamePlayer);

//获得类的class loader
ClassLoader c1 = gamePlayer.getClass().getClassLoader();
//动态产生一个代理
IGamePlayer proxy = (IGamePlayer) Proxy.newProxyInstance(c1, new Class[]{IGamePlayer.class}, handler);

System.out.println("开始时间---->");
proxy.login("zhangsan", "password");
proxy.killBoss();
proxy.upgrade();
System.out.println("结束时间---->");
}
}


注:InvocationHandler接口是JDK提供的动态代理接口,又被代理类的方法进行代理。

动态代理通用类图及源码



抽象主题

public interface Subject {

//业务逻辑处理
public void doSomething(String str);
}


真实主题

public class RealSubject implements Subject {

//业务逻辑处理
@Override
public void doSomething(String str) {
System.out.println("do something ..." + str);
}
}


动态代理的Handler类

public class MyInvocationHandler implements InvocationHandler {

//被代理的对象
private Object object = null;
//普通构造函数传递一个对象
public MyInvocationHandler(Object _object) {
this.object = _object;
}
//代理方法
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return method.invoke(this.object, args);
}
}


动态代理类

public class DynamicProxy<T> {

@SuppressWarnings("unchecked")
public static <T> T newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler) {
// 寻找JoinPoint连接点
if (true) {
//执行一个前置通知
(new BeforeAdvice()).exec();
}
return (T) Proxy.newProxyInstance(loader, interfaces, handler);
}
}


通知类 (接口)

public interface IAdvice {

public void exec();
}


前置通知类

public class BeforeAdvice implements IAdvice {

@Override
public void exec() {
System.out.println("我是前置通知,我通知了...");
}
}


场景类

public class Client {

public static void main(String[] args) {

Subject subject = new RealSubject();
InvocationHandler handler = new MyInvocationHandler(subject);
Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), handler);
proxy.doSomething("Finish");
}
}


注:

动态代理的主要意图就是解决常说的“审计”问题,也就是面向切面编程,在不改变我们已有代码结构情况下增强或控制对象的行为。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: