`
conkeyn
  • 浏览: 1522873 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

代理,jdk proxy

 
阅读更多

引用:http://javahowto.blogspot.com/2011/12/java-dynamic-proxy-example.html

In this post, I will go over the basic constructs of dynamic proxy, followed by some notes and things to watch out when implementing it. First, the 5 elements of a dynamic proxy as implemented in this example:

TestImpl: the class behind the proxy, not to be directly invoked by the client. In some cases, this type may not exist.

TestIF: the proxy interface implemented by TestImpl, and the dynamic proxy. This is the interface type the client should reference. One or more interfaces are required to create dynamic proxy. If there is no such interface, you may need to dynamically generate them with tools like ASM.

TestInvocationHandler: the InvocationHandler that handles method invocation on the proxy from the client. It contains an instance of TestImpl to delegate method invocations to.

Test: the test main class.

$Proxy0: the dynamic proxy that implements TestIF, and the client-facing implementation of TestIF.

 

public interface TestIF {
    String hello(String name);
}

 

public class TestImpl implements TestIF {
public String hello(String name) {
   return String.format("Hello %s, this is %s", name, this);
}
}

 

import java.lang.reflect.*;
public class TestInvocationHandler implements InvocationHandler {
private Object testImpl;

public TestInvocationHandler(Object impl) {
   this.testImpl = impl;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) 
        throws Throwable {
   if(Object.class  == method.getDeclaringClass()) {
       String name = method.getName();
       if("equals".equals(name)) {
           return proxy == args[0];
       } else if("hashCode".equals(name)) {
           return System.identityHashCode(proxy);
       } else if("toString".equals(name)) {
           return proxy.getClass().getName() + "@" +
               Integer.toHexString(System.identityHashCode(proxy)) +
               ", with InvocationHandler " + this;
       } else {
           throw new IllegalStateException(String.valueOf(method));
       }
   }
   return method.invoke(testImpl, args);
}
}

 

import java.lang.reflect.*;
public class Test {
public static void main(String... args) {
   TestIF t = (TestIF) Proxy.newProxyInstance(TestIF.class.getClassLoader(),
                           new Class<?>[] {TestIF.class},
                           new TestInvocationHandler(new TestImpl()));
   System.out.printf("t.hello(Duke): %s%n", t.hello("Duke"));
   System.out.printf("t.toString(): %s%n", t);
   System.out.printf("t.hashCode(): %H%n", t);
   System.out.printf("t.equals(t): %B%n", t.equals(t));
   System.out.printf("t.equals(new Object()): %B%n", t.equals(new Object()));
   System.out.printf("t.equals(null): %B%n", t.equals(null));
}
}

 Implementation notes:

When dispatching method invocations on proxy to delegate object, 3 methods from java.lang.Object need special handling: toString(), hashCode() and equals(Object). Since they are related to the proxy object identity, they should be serviced directly by the handler. One option is to base their return values on the proxy param, as in this example.

Other public methods from java.lang.Object are all final, and are not routed to the InvocationHandler by JVM. These methods are:

public final native Class<?> getClass();
public final native void notify();
public final native void notifyAll();
public final native void wait(long timeout) throws InterruptedException;
public final void wait(long timeout, int nanos) throws InterruptedException;
public final void wait() throws InterruptedException

The handler's invoke method should not invoke methods on the proxy object passed in as the first param (except the 6 final methods listed above), to avoid infinite loop and StackOverflowError. For example, this following debug line should not be used:
// AVOID THIS

System.out.printf("proxy=%s, method=%s, args=%s%n",proxy, method, Arrays.toString(args));

If the handler already knows how to acquire the delegate TestImpl instance, through either direct instantiation or lookup, it can hide it completely from the client. So the only type of TestIF the client knows is the proxy.

The Object[] args passed into handler's invoke method is null, when the invoked method takes no param. This can come as a surprise to many. So a null check is needed before operating on args.

To run this example after compiling all java classes:

$ java Test
t.hello(Duke): Hello Duke, this is TestImpl@a3901c6
t.toString(): $Proxy0@24a37368, with InvocationHandler TestInvocationHandler@66edc3a2
t.hashCode(): 24A37368
t.equals(t): TRUE
t.equals(new Object()): FALSE
t.equals(null): FALSE

 
To save/keep/dump the generated proxy class file (with non-standard option):

$ java -Dsun.misc.ProxyGenerator.saveGeneratedFiles=true Test

To view the structure of the proxy class:

$ $JAVA_HOME/bin/javap -v \$Proxy0

 

 

分享到:
评论

相关推荐

    静态代理 动态代理 jdk Proxy

    自己写的小例子,供学习参考。 public class StaticProxy implements Hello{ private HelloSpecker helloSpecker; public StaticProxy() { } public StaticProxy(HelloSpecker helloSpecker) { ...

    JdkProxy.java

    JdkProxy.java

    Aop jdk proxy实现小例子

    JDK Proxy是Java提供的一种动态代理机制,它是实现AOP的一种方式。通过JDK Proxy,我们可以在运行时创建一个接口的实现类,并在调用接口方法时插入自定义的处理逻辑,这就是AOP的核心思想——“织入”(Weaving)。...

    Spring_0300_JDKProxy

    标题"Spring_0300_JDKProxy"暗示我们将讨论Spring如何使用JDK的Proxy类来实现动态代理。在Spring中,`org.springframework.aop.framework.ProxyFactoryBean`或`org.springframework.aop.framework.ProxyFactory`可以...

    JDK动态代理proxy

    JDK动态代理,全称为Java Dynamic Proxy,是Java标准库提供的一种强大且灵活的机制,允许我们在运行时创建代理类来实现指定的接口。这种机制主要用于实现AOP(面向切面编程)或为已有接口提供额外的功能,如日志、...

    java代理方法假设和验证的Proxy源码分析.docx

    在Java中,代理主要通过两种方式实现:接口代理(基于Java动态代理JDK Proxy)和类代理(基于CGLIB等库)。本文关注的是JDK的动态代理,它允许我们为给定的接口创建代理类,以便在调用接口方法时插入自定义逻辑。 ...

    mybatis_jdk_proxy.zip

    针对标题"mybatis_jdk_proxy.zip",我们可以推断这是一个关于MyBatis框架使用Java JDK代理(JDK Proxy)的相关学习资料。下面将详细解释这个主题。 MyBatis是一个流行的持久层框架,它允许开发者通过简单的XML或...

    JDK动态代理_JDK动态代理

    JDK动态代理的核心API包括`java.lang.reflect.Proxy`和`java.lang.reflect.InvocationHandler`。 - **`java.lang.reflect.Proxy`**:提供了创建动态代理类和实例的方法。通过`newProxyInstance`方法,传入...

    动态代理cglibjar包和源码

    5. **CGLIB与Java内置动态代理JDK Proxy的区别**: - JDK Proxy基于接口实现,而CGLIB基于继承,因此CGLIB可以代理没有接口的类。 - JDK Proxy性能相对较慢,因为涉及到反射,而CGLIB通过字节码生成,性能更好。 ...

    java代理机制 JDK动态代理和cglib代理 详解

    - `Proxy`类是JDK动态代理的工厂,它提供静态方法`newProxyInstance()`用于创建代理对象。 - 创建代理对象需要三个参数:类加载器、目标接口数组和InvocationHandler实例。 二、CGLIB代理 CGLIB(Code Generation...

    JDK代理和Cglib代理

    JDK动态代理是Java标准库提供的一种代理机制,位于`java.lang.reflect`包下的`Proxy`类和`InvocationHandler`接口。JDK代理主要基于接口来实现,也就是说,只有实现了特定接口的目标对象才能通过JDK代理进行增强。 ...

    关于jdk动态代理的源码剖析

    2. **生成代理类**:通过JDK提供的`Proxy`类的静态方法`newProxyInstance`可以生成一个代理对象。该方法接受三个参数:类加载器、代理类需要实现的接口数组以及`InvocationHandler`实例。 ```java ClassLoader ...

    浅谈JDK动态代理与CGLIB代理去区别

    首先,JDK动态代理主要依赖于java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。Proxy类用于创建一个代理对象,而InvocationHandler接口则定义了处理代理对象调用方法的逻辑。当调用代理对象的...

    jdk动态代理技术详解

    Proxy 类是 JDK 中的动态代理类,是动态代理的核心类,其作用类似于代理模式中的代理。Proxy 类中包含的全是静态的方法和成员变量,这是一个纯粹的工具类,因此其源代码中含有一个私有的构造器,在某种意义上可以看...

    JDK动态代理和CGLIB代理

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

    spring jdk动态代理

    Spring AOP允许我们通过代理来实现横切关注点,如日志、事务管理等,而JDK动态代理则是Spring AOP实现的一种方式。本文将深入探讨Spring如何利用JDK动态代理技术来实现这一功能,并通过实例解析其底层实现。 首先,...

    java 动态代理实例(JDK代理与CGLIB代理)

    **JDK代理**是基于接口的代理,它通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口实现。当我们的目标对象实现了特定的接口时,我们可以使用JDK动态代理来创建该对象的代理。以下是JDK...

    java动态代理(JDK和cglib).pdf

    在JDK动态代理中,我们可以通过`Proxy.newProxyInstance()`方法创建代理对象,传入`ClassLoader`、接口列表和`InvocationHandler`实例,这样当调用代理对象的方法时,实际执行的是`InvocationHandler`的`invoke()`...

    设计模式之代理模式proxy.zip

    JDK动态代理基于接口实现,它要求目标对象必须实现至少一个接口,然后通过Proxy类和InvocationHandler接口来创建并控制代理对象。当我们调用代理对象的方法时,实际执行的是InvocationHandler的invoke方法,这样可以...

    JDK动态代理简单示例

    JDK动态代理是Java编程中一个非常重要的特性,它允许我们在运行时创建具有特定接口的代理类实例。这种技术在很多场景下都非常有用,比如在AOP(面向切面编程)中实现方法拦截、日志记录、事务管理等。下面我们将深入...

Global site tag (gtag.js) - Google Analytics