动态代理模式(抽象角色用接口形式,代理角色必须实现InvocationHandler)
2016-01-09 23:13
513 查看
动态代理
接口UserManager
[java] viewplaincopyprint?
/***
* 用户控制接口
* @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] viewplaincopyprint?
/****
* 用户管理真正的实现类
* @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] viewplaincopyprint?
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] viewplaincopyprint?
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
相关文章推荐
- [Python标准库]operator——内置操作符的函数接口
- uva 11536 - Smallest Sub-Array
- Python读写文件实际操作的五大步骤
- 引用于指针的区别
- 1076. Forwards on Weibo (30)【树+搜索】——PAT (Advanced Level) Practise
- mac学习笔记之:使用brew安装软件
- ASP.NET服务器控件的生命周期分析
- angularjs[ngRepeat:dupes]
- 【HTML/XML 4】实例分析HTML和XML的不同
- hdu1171
- 【HTML/XML 4】实例分析HTML和XML的不同
- Web Service学习笔记(webservice、soap、wsdl、jws详细分析)
- 24种设计模式
- ASP.NET服务器端控件原理分析
- C# 扩展方法
- redis第一天
- Codeforces 615D Multipliers (Round #338 (Div. 2) D题)
- js常用正则表达式
- conda
- 零基础写Java知乎爬虫之进阶篇