您的位置:首页 > 其它

动态代理模式(抽象角色用接口形式,代理角色必须实现InvocationHandler)

2016-01-09 23:13 513 查看


动态代理


接口UserManager

[java] view
plaincopyprint?

/***

* 用户控制接口

* @author Administrator

*

*/

public interface UserManager {

public void addUser(String userId,String userName);

public void modifyUser(String userId,String userName);

public void delUser(String userId);

public String findUser(String userId);

}


实现类UserManagerImpl

[java] view
plaincopyprint?

/****

* 用户管理真正的实现类

* @author Administrator

*

*/

public class UserManagerImpl implements UserManager {

/*****

* 添加用户

*/

public void addUser(String userId, String userName) {

System.out.println("正在添加用户,用户为:"+userId+userName+"……");

}

/*****

* 删除用户

*/

public void delUser(String userId) {

System.out.println("delUser,userId="+userId);

}

/***

* 查找用户

*/

public String findUser(String userId) {

System.out.println("findUser,userId="+userId);

return userId;

}

public void modifyUser(String userId, String userName) {

System.out.println("modifyUser,userId="+userId);

}

}


代理类LogHandler

[java] view
plaincopyprint?

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

public class LogHandler implements InvocationHandler {

private Object targetObject;

public Object newProxyInstance(Object targetObject) {

this.targetObject = targetObject;

return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),

targetObject.getClass().getInterfaces(), this);

}

public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {

Object ret = null;

try {

System.out.println("正在进行操作前的准备工作……");

//调用目标方法

ret = method.invoke(targetObject, args);

System.out.println("操作成功,正在进行确认处理……");

} catch (Exception e) {

e.printStackTrace();

System.out.println("error-->>" + method.getName());

throw e;

}

return ret;

}

}


客户端Client

[java] view
plaincopyprint?

public class Client {

/**

* @param args

*/

public static void main(String[] args) {

LogHandler logHandler = new LogHandler();

UserManager userManager = (UserManager)logHandler.newProxyInstance(new UserManagerImpl());

userManager.findUser("0001");

}

}


运行结果




时序图




总结

动态代理模式通过使用反射,可以在运行期决定加载哪个类,避免了一个类对应一个代理的问题;同时,通过统一的invoke方法,统一了代理类对原函数的处理过程,使用动态代理很大程度上减少了重复的代码,降低了维护的复杂性和成本。

//**********************************************

接口

package com.ygl.dynamicproxy;

public interface Subject {

public void request();

}

//*********************

package com.ygl.dynamicproxy;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

/**

* 该代理类的内部属性是Object类型,实际使用时通过该类的构造方法传递进来一个对象

* 此外,该类还重写了invoke方法,该方法中的method。invoke其实就是被代理对象(真实对象)的将要执行的方法,

* 方法参数subject表示该方法属于subject对象,通过动态代理类,我们可以在执行真实对象的方法前后加入自己的方法

* @author lenovo

*

*/

public class DynamicSubject implements InvocationHandler{

private Object subject;

public DynamicSubject(Object obj){

this.subject=obj;

}

@Override

public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {

System.out.println("bfore calling"+method);

method.invoke(subject, args);

System.out.println("after calling"+method);

return null;

}

}

//**************************************

package com.ygl.dynamicproxy;

public class RealSubject implements Subject {

@Override

public void request() {

System.out.println("RealSubject");

}

}

//********************************

package com.ygl.dynamicproxy;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Proxy;

public class Client {

public static void main(String[] args) {

RealSubject realSubject=new RealSubject();

InvocationHandler handler=new DynamicSubject(realSubject);

Class<?> clazz=handler.getClass();

System.out.println(clazz);

//下面的代码一次性生成代理

//传入真实角色实现的接口 realSubject.getClass().getInterfaces(),得到的subject是一个代理的实例class $Proxy0其实现了 realSubject.getClass().getInterfaces()这些接口

Subject subject=(Subject)Proxy.newProxyInstance(clazz.getClassLoader(), realSubject.getClass().getInterfaces(), handler);

System.out.println(subject.getClass());//class $Proxy0

subject.request();//此时会执行相应handler里的invoke方法

}

}

//*******************

class com.ygl.dynamicproxy.DynamicSubject

bfore callingpublic abstract void com.ygl.dynamicproxy.Subject.request()

RealSubject

after callingpublic abstract void com.ygl.dynamicproxy.Subject.request()

class $Proxy0
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: