`
jiagou
  • 浏览: 2538075 次
文章分类
社区版块
存档分类
最新评论

说说动态代理

 
阅读更多

在文章代理模式之静态代理(2)中我们了解到静态代理的运行机制.同时在文章的尾部看到了静态代理的不足.而动态代理可以弥补那些不足,接下来我们将详细的来了解一下动态代理.

JavaJava.lang.reflect包中提供Proxy类和InvocationHandler.我们可以通过他们两个生成动态的JDK动态代理类或者动态代理对象.

一个类:Proxy(动态生成一个代理对象)必须这个类实现了接口才可以生成代理,如果没有接口的话就不能生成代理.它是通过接口在内存中建立一个类.

一个接口:Interface InvocationHandler.系统生成的每个代理对象都有一个与之相对应的InvocationHandler对象.

具体代码示例:

由于在上文中的接口类和目标类没有进行更改,这里不再赘述.需要更改的是将原来的静态代理中手动添加的代理类删除.取而代之的是一个实现InvocationHandler接口的LogHandler;

LogHandler:(在原有的基础之上添加日志功能)


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.text.SimpleDateFormat;

public class LogHandler implements InvocationHandler {
	
	//对目标对象生成代理对象,需要将目标对象传过来.可以使用构造方法和下面的方法
	private Object targetObject;
	public Object newProxyInstance(Object targetObject){
		 this.targetObject=targetObject;
		//根据传来的对象动态生成代理
		//第一个参数是类加载器,需要和目标对象的类加载器一样.
		//第二个参数是目标类的所有接口.会根据接口创建出代理类,代理类具有目标类的所有方法,但是方法里没有任何东西.
		//第三个参数需要回调InvocationHandler中的invoke方法.也就是实现InvocationHandler的对象.
		 return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);
			
		
	}
	
	/**
	 * method表示代理目标的方法,可以动态进行获取
	 */
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		//获得当前时间
		 SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		 String datetime = tempDate.format(new java.util.Date());
		 
		//方法开始日志记录
		System.out.println("startTime: "+datetime+"   start-->>"+method.getName());
		
		//方法的相关参数
		for(int i=0;i<args.length;i++){
			System.out.println(args[i]);
		}
		
		//方法的返回值
		Object result=null;
		try{
			
			//调用目标的方法
			result =method.invoke(targetObject, args);
			
			//方法成功日志记录
			System.out.println("successTime: "+datetime+"   success-->>"+method.getName());
			
		}catch(Exception e){
			e.printStackTrace();
			
			//方法失败日志记录
			System.out.println("errorTime: "+datetime+"   error-->>"+method.getName());
			throw e;
		}
		
		return result;
	}

}


客户端代码:

/**
 * 添加一个用户
 */
public class Client {
	public static void main(String[] args){
		
		LogHandler logHandler=new LogHandler();
		UserManager userManager=(UserManager)logHandler.newProxyInstance(new UserManagerImpl());
		userManager.addUser("00001", "刘德华");
	}
}

执行结果如下:

startTime: 2012-08-10 16:49:37start-->>addUser

00001

刘德华

UserManagerImpl.addUser()userId-->00001

successTime: 2012-08-10 16:49:37success-->>addUser


使用动态代理,我们可以看到非常好的解耦效果.当然,在我们使用Proxy的时候也不是随意的用的,通常都是为一个指定的目标对象来生成动态代理.这种动态代理在AOP(AspectOrient Program)面向切面编程中称之为AOP代理.AOP代理可以替代目标对象,并且包含目标对象的全部方法,同时在已有方法的基础之上向前,向后加入一些通用处理的方法,例如上例中的日志处理.

通过对动态代理模式的研究和学习可以看到编程的艺术性,同时也在演绎着面向对象的核心思想.

分享到:
评论

相关推荐

    手机QQ协议、3GQQ协议的SDK、QQ空间协议、webQQ协议

    CHttpWeb类 用户可以自定义发送数据包:public string HttpSendData(string URL, string Method = "GET", string Data = "",string Encode = "UTF-8") 可以自定义设置Referer、UserAgent、代理、获取cookie、带上...

    Java面试题.docx

    12、静态代理和动态代理的区别,什么场景使用? 14、Java中实现多态的机制是什么? 16、说说你对Java反射的理解 17、说说你对Java注解的理解 18、Java中String的了解 19、String为什么要设计成不可变的? 20、...

    2021互联网大厂Java架构师面试题突击视频教程

    35_dubbo支持哪些负载均衡、高可用以及动态代理的策略? 36_SPI是啥思想?dubbo的SPI机制是怎么玩儿的? 37_基于dubbo如何做服务治理、服务降级以及重试? 38_分布式系统中接口的幂等性该如何保证?比如不能重复扣款...

    安卓java读取网页源码-questions:自问自答

    什么是动态代理 在 Java 中 wait、yield 和 seelp 方法的不同 描述下 Java 中的内存分配 什么是多态,实现多态的机制是什么 接口(Interface)与抽象类(Abstract Class)的区别 重写(Override)与重载(Overload)...

    浅析nginx刚刚发布的JavaScript能力nginScript

    Nginx也更开发的走向了动态配置化的下一个阶段。大家可以点击查看 官方介绍链接 。 先简单说说nginx Nginx [engine x]是全球最受欢迎,也是最优秀的web服务器、反向代理服务器。通过第三方公司的统计,目前全球至少...

    web路径探测工具 7kbscan-WebPathBrute 1.5.8 (集成三字典)

    一、先说说并发线程数吧,虽然默认是20 但是加大也无妨看你自己的各个参数设置和机器网络等配置了。 二、超时时间自己视情况而定也不必多介绍了。 三、这个随机xff头和xr头套用百度上一段话能懂得自然懂得不懂得也...

    Dhcp两大威胁以及arp欺骗等试验总结

    还是说说cisco交换机吧。一般采取动态获取IP地址的上网方式比较多,先配置ip dhcp snooping 再配置ip arp inspection,此时,客户端就应该没办法伪造其它主机去伪造网关,因为这些伪造的arp reply报文在网关看来都是...

    Ext 开发指南 学习资料

    代理proxy和目标target 7.4. yui自远方来,不亦乐乎 7.4.1. Basic,基础 7.4.2. Handles,把手 7.4.3. On Top,总在上边 7.4.4. Proxy,代理 7.4.5. Groups,组 7.4.6. Grid,网格 7.4.7. Circle,圆形 7.4.8. ...

    asp.net知识库

    动态调用对象的属性和方法——性能和灵活性兼备的方法 消除由try/catch语句带来的warning 微软的应试题完整版(附答案) 一个时间转换的问题,顺便谈谈搜索技巧 .net中的正则表达式使用高级技巧 (一) C#静态成员和...

    EXT教程EXT用大量的实例演示Ext实例

    代理proxy和目标target 8. 哭泣吧!现在才开始讲基础问题。 8.1. Ext.get 8.2. 要是我们想一下子获得一堆元素咋办? 8.3. DomHelper和Template动态生成html 8.3.1. DomHelper用来生成小片段 8.3.2. 批量生成...

    EXT2.0中文教程

    代理proxy和目标target 8. 哭泣吧!现在才开始讲基础问题。 8.1. Ext.get 8.2. 要是我们想一下子获得一堆元素咋办? 8.3. DomHelper和Template动态生成html 8.3.1. DomHelper用来生成小片段 8.3.2. 批量生成还是...

    超级有影响力霸气的Java面试题大全文档

    EJB容器是EJB组件的代理, EJB组件由容器所创建和管理。客户通过容器来访问真正的EJB组件。 24、Static Nested Class 和 Inner Class的不同。 Static Nested Class是被声明为静态(static)的内部类,它可以不...

    java 面试题 总结

    EJB容器是EJB组件的代理,EJB组件由容器所创建和管理。客户通过容器来访问真正的EJB组件。 21、Static Nested Class 和 Inner Class的不同。 Static Nested Class是被声明为静态(static)的内部类,它可以不依赖...

Global site tag (gtag.js) - Google Analytics