`
li_sir
  • 浏览: 114797 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java动态代理之一:java Proxy实现

    博客分类:
  • java
阅读更多
动态代理类是一个实现在创建类时在运行时指定的接口列表的类。

InvocationHandler handler = new MyInvocationHandler(...);
     Class proxyClass = Proxy.getProxyClass(
         Foo.class.getClassLoader(), new Class[] { Foo.class });
     Foo f = (Foo) proxyClass.
         getConstructor(new Class[] { InvocationHandler.class }).
         newInstance(new Object[] { handler });

proxyClass 是一份动态生成的字节码,在创建时需指定一个加载器 Foo.class.getClassLoader()(在此可理解为:给他指定一个妈妈),给它一个接口对象数组,即该代理类实现了哪些接口。
调用 Class proxyClass = Proxy.getProxyClass(
         Foo.class.getClassLoader(), new Class[] { Foo.class });
即生成了一个动态字节码。通过反射查看它的构造函数,发现它的构造函数需要传递一个InvocationHandler 对象。 其实在生成的动态字节码实现接口的方法中,都是调用了InvocationHandler 对象的invoke方法。
在这里我们可以大概想象生成的动态字节码的内部结构:
public classs Xxx$Proxy{
private InvocationHandler  invocationHandler ;
public Xxx$Proxy(InvocationHandler  invocationHandler  ){
this.invocationHandler =invocationHandler ;
}
Method1(Object[] args){
invocationHandler.invoke(this,...);
}
Method2(Object[] args){
invocationHandler.invoke(this,...);
}

}


引用
我们在看InvocationHandler 接口,其内部就一个方法
Object invoke(Object proxy,
              Method method,
              Object[] args)
              throws Throwable

需要一个代理对象,方法对象,方法参数。

通常我们在InvocationHandler实现类中,放入真实的角色和Advice(增强功能类)。
在通过反射执行method对象的Invoke方法时,传入真实对象。

上面代理实现是通过分部执行,Proxy类的newProxyInstance(Foo.class.getClassLoader(),
                                          new Class[] { Foo.class },
                                          handler);

方法可以一次生成该代理对象,由以上的解释,我们不难想象需要三个参数。即给它个妈妈(加载器),实现了那些接口(接口数组),InvocationHandler对象。

下面是一个动态代理工厂:


public class ProxyFactoryBean {

	private Advice advice;
	private Object target;
	
	public Advice getAdvice() {
		return advice;
	}

	public void setAdvice(Advice advice) {
		this.advice = advice;
	}

	public Object getTarget() {
		return target;
	}

	public void setTarget(Object target) {
		this.target = target;
	}

	public Object getProxy() {
		Object proxy = Proxy.newProxyInstance(
				target.getClass().getClassLoader(),
				target.getClass().getInterfaces(),
				new InvocationHandler(){
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {
						advice.beforeMethod(method);
						Object retVal = method.invoke(target, args);
						advice.afterMethod(method);
						return retVal;						
						
					}
				}
				);
		return proxy;
	}



我们可以动态的指定一个代理目标target,和增强功能对象advice。使用getProxy即会生成一个动态代理对象。

该种代理方式,代理的对象必须是实现了某个接口。
分享到:
评论
2 楼 li_sir 2011-03-30  
Method.invoke 就调用的是要代理的对象proxied的方法
1 楼 hxtoyou 2011-03-29  
写的很好  看明白了点InvocationHandler的作用,但是对Invoke函数还是有点迷茫 ,下面是《java编程思想》里面的代码:

public class DynamicProxyHandler implements InvocationHandler {
private Object proxied;

public DynamicProxyHandler(Object proxied) {
this.proxied = proxied;
}

public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("**** proxy: " + proxy.getClass() + ",method: "
+ method + ",args: " + args);
if (args != null)
for (Object arg : args)
System.out.println(" " + arg);
return method.invoke(proxied, args);
}
}
对于这里的DynamicProxyHandler中传入的proxied参数,我发现只是把它赋值到这个函数中,并没有在第一个invoke函数中调用 ,就在return中返回了。。还有就是在第一个invoke函数中第一个参数proxy不明白是什么作用

相关推荐

    java Proxy 动态代理

    在Java中,动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类是用于创建一个代理对象,而InvocationHandler接口则定义了代理对象调用方法时的行为。 1. **...

    Java动态代理实现 Proxy InvocationHandler

    总结来说,Java动态代理通过`Proxy`和`InvocationHandler`提供了灵活的代码扩展机制,可以在运行时为对象创建代理,实现在不修改原有代码的基础上添加额外功能。这在处理需要拦截和增强的对象时非常有用,例如日志...

    Java动态代理两种实现方式

    JDK动态代理是通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现的。Proxy类用于创建一个代理对象,而InvocationHandler接口定义了处理代理对象方法调用的逻辑。 #### 1. 创建...

    java动态代理实现详解

    Java 动态代理是Java平台提供的一种强大的工具,它允许我们在运行时动态生成代理类,这些代理类可以实现一组指定的接口,同时还能在方法调用前后添加自定义的行为。这种机制大大简化了面向切面编程(AOP)和事件监听...

    Java实现动态代理

    代理类是由Proxy类的`newProxyInstance()`方法创建的,它需要三个参数:一个类加载器,一个接口数组,以及一个InvocationHandler实例。当通过代理对象调用方法时,实际执行的是InvocationHandler的`invoke()`方法。 ...

    java动态代理 经典文章(word 2007格式的)

    Java动态代理是Java编程中一个重要的特性,它允许在运行时创建代理对象,这些代理对象可以代表并增强原对象的功能。动态代理主要应用于面向切面编程(AOP)和事件监听等场景,使得代码更加模块化,易于维护。以下是...

    Java动态代理[动态类Proxy的使用]

    总的来说,Java动态代理为我们提供了一种灵活的编程模式,让我们可以在不修改原有代码的情况下扩展或增强已有类的行为,这对于实现AOP和工具类的构建非常有用。理解和熟练使用`java.lang.reflect.Proxy`可以帮助我们...

    java 实现HTTP PROXY

    Java实现HTTP PROXY是一个常见的需求,特别是在开发网络应用或者测试环境中,我们可能需要通过代理服务器转发HTTP请求。本文将深入探讨如何使用Java编程语言来创建一个HTTP代理服务器,并且会涉及相关的源码分析。 ...

    java动态代理demo

    Java动态代理是Java编程中一个重要的特性,它允许我们在运行时创建代理对象,这些代理对象可以代表并增强原对象的功能。动态代理在很多场景下都非常有用,比如日志记录、性能监控、事务管理等。本示例将带你深入理解...

    java动态代理实例

    在Java中,动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。`Proxy`类用于创建代理对象,而`InvocationHandler`接口定义了处理代理对象方法调用的逻辑。 1. **...

    java 动态代理实现AOP

    Java动态代理是Java语言提供的一个强大的特性,它允许开发者在运行时创建代理对象,以实现对目标对象的方法调用拦截。动态代理主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。...

    JAVA实现动态代理的简单流程

    这是因为Java动态代理的核心在于生成一个实现了特定接口的代理对象,因此必须先有接口作为代理的基础。 ```java interface AA { void method(); } class Ab implements AA { @Override public void method() { ...

    java proxy demo 代理类的运用demo

    Java代理类是面向切面编程(AOP)的一种实现方式,它允许我们在不修改原有代码的情况下,为已有的对象提供额外的功能。在这个“java proxy demo”中,我们将深入探讨如何利用Sun JDK API来创建和使用Java动态代理。 ...

    用Java动态代理实现AOP

    在Java中,动态代理可以用来实现AOP,通过 InvocationHandler接口提供一个执行处理器,然后通过Proxy类获取一个代理对象,通过这个代理对象来执行商业方法。在商业方法被调用时,执行处理器会被自动调用,从而实现了...

    java动态代理新java动态代理新java动态代理新

    Java动态代理是Java反射API提供的一个高级特性,主要用于实现对对象方法的调用拦截。动态代理允许我们在运行时创建一个接口的实现类实例,而无需提前知道其具体实现细节。这在很多框架(如Spring AOP)中得到了广泛...

    Java代理模式Java动态代理

    ### Java代理模式与Java动态代理详解 #### 一、代理模式概述 代理模式是一种软件设计模式,它在客户端和目标对象之间提供了一种间接层。这种模式的主要目的是控制客户端对目标对象的访问,并且可以在不修改原有...

    java动态代理例子

    Java动态代理是Java编程中一个重要的特性,它允许我们在运行时创建代理类,这些代理类可以作为原有类的代理,从而在不修改原有类代码的情况下,扩展或增强原有类的功能。这里我们将深入探讨两个主要的Java动态代理...

    java 设计模式之代理模式(Proxy Pattern)实现代码及设计详解:动态代理模式、静态代理模式

    Java通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现动态代理。动态代理的优势在于,我们不需要为每个目标类都创建一个代理类,只需要一个代理类就能代理多个实现了相同接口的...

Global site tag (gtag.js) - Google Analytics