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

JDK Proxy AOP实现

阅读更多

JDK Proxy AOP实现

java.lang.reflect.Proxy,
Proxy
提供用于创建动态代理类和实例的静态方法. 只能针对接口创建代理
newProxyInstance()
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序
(
详见api文档)

java.lang.reflect.InvocationHandler,
InvocationHandler
是代理实例的调用处理程序 实现的接口。
invoke()
在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。

 

动态代理的使用代码示例如下:
 1 public static void main(String[] args) {
 2         
 3         InvocationHandler ih = new InvocationHandler() {
 4 
 5             public Object invoke(Object proxy, Method method, Object[] args)
 6                     throws Throwable {
 7                 // 拦截方法处理
 8                 return null;
 9             }
10             
11         };
12         
13         Class<?>[] interfaces = new Class<?>[] {BankAccount.class};
14         
15         BankAccount bankAccount = (BankAccount) Proxy.newProxyInstance(ProxyTest  
16                 .class.getClassLoader(), interfaces, ih);  
17   }
18 

 

下面是动态代理生成的代码对应(通过反编译工具对字节码进行处理)

接口代码:

 

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> 1 public interface BankAccount {
 2 
 3     boolean deposit(BigDecimal money);
 4     
 5     boolean withdraw(BigDecimal money);
 6     
 7     String getName();
 8     
 9     String getId();
10 }
11 

 

动态代理生成的字节码(反编译后的Java代码)

 

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> 1 public final class BankAccount$1 extends Proxy implements BankAccount {
 2     private static Method m6; // getId
 3     private static Method m4; // withdraw
 4     private static Method m5; // getName
 5     private static Method m2; // toString
 6     private static Method m0; // hashCode
 7     private static Method m3; // deposit
 8     private static Method m1; // equals
 9 
10     public BankAccount$1(InvocationHandler ih) {
11         super(ih);
12     }
13 
14     public final String getId() {
15         try {
16             return (String) this.h.invoke(this, m6, null);
17         } catch (RuntimeException e) {
18             throw e;
19         } catch (Throwable t) {
20             throw new UndeclaredThrowableException(t);
21         }
22     }
23 
24     public final boolean withdraw(BigDecimal paramBigDecimal) {
25         try {
26             return ((Boolean) this.h.invoke(this, m4,
27                     new Object[] { paramBigDecimal })).booleanValue();
28         } catch (RuntimeException e) {
29             throw e;
30         } catch (Throwable t) {
31             throw new UndeclaredThrowableException(t);
32         }
33     }
34 
35     public final String getName() {
36         try {
37             return (String) this.h.invoke(this, m5, null);
38         } catch (RuntimeException e) {
39             throw e;
40         } catch (Throwable t) {
41             throw new UndeclaredThrowableException(t);
42         }
43     }
44 
45     public final String toString() {
46         try {
47             return (String) this.h.invoke(this, m2, null);
48         } catch (RuntimeException localRuntimeException) {
49             throw localRuntimeException;
50         } catch (Throwable t) {
51             throw new UndeclaredThrowableException(t);
52         }
53     }
54 
55     public final int hashCode() {
56         try {
57             return ((Integer) this.h.invoke(this, m0, null)).intValue();
58         } catch (RuntimeException e) {
59             throw e;
60         } catch (Throwable t) {
61             throw new UndeclaredThrowableException(t);
62         }
63     }
64 
65     public final boolean deposit(BigDecimal paramBigDecimal) {
66         try {
67             return ((Boolean) this.h.invoke(this, m3,
68                     new Object[] { paramBigDecimal })).booleanValue();
69         } catch (RuntimeException localRuntimeException) {
70             throw localRuntimeException;
71         } catch (Throwable localThrowable) {
72             throw new UndeclaredThrowableException(localThrowable);
73         }
74     }
75 
76     static {
77         try {
78             m6 = Class.forName("BankAccount").getMethod("getId"new Class[0]);
79             m4 = Class.forName("BankAccount").getMethod("withdraw",
80                     new Class[] { Class.forName("java.math.BigDecimal") });
81             m5 = Class.forName("BankAccount")
82                     .getMethod("getName"new Class[0]);
83             m2 = Class.forName("java.lang.Object").getMethod("toString",
84                     new Class[0]);
85             m0 = Class.forName("java.lang.Object").getMethod("hashCode",
86                     new Class[0]);
87             m3 = Class.forName("BankAccount").getMethod("deposit",
88                     new Class[] { Class.forName("java.math.BigDecimal") });
89             m1 = Class.forName("java.lang.Object").getMethod("equals",
90                     new Class[] { Class.forName("java.lang.Object") });
91         } catch (NoSuchMethodException e) {
92             throw new NoSuchMethodError(e.getMessage());
93         } catch (ClassNotFoundException e) {
94             throw new NoClassDefFoundError(e.getMessage());
95         }
96     }
97 }
98 

 

从动态代理生成的代码可以分析得到,所有的方法的调用,都会回调InvokeHanlder接口的实现类的invoke方法,并把实际调用的反射相关信息作为参数传给invoke方法。

 

Cglib Proxy AOP实现

cglib是一个开源项目! 是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。Spring很多地方借助该项目实现AOP的功能封装。

CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。通过使用CGLIB来为那些没有接口的类创建代理对象。

 

CglibProxyJDK Proxy还是有一定的相似的,下面的例子,给大家一个基本的演示

 

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1 public class SimpleBean {
2 
3     public void hello() {
4         System.out.println("hi matthew!");
5     }
6 }

Cglib 代理后(只给出了部分核心反编译后的Java代码)

 

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> 1 class  SimpleBean$$EnhancerByCGLIB$$4c4a66a extends SimpleBean {
 2     private  static  final  Method CGLIB$hello$0$Method ;
 3 
 4     public  final  void  hello( ) {
 5     if(!this.CGLIB$CONSTRUCTED)
 6     {
 7       super.hello();
 8       return;
 9    
10     }
11     if(this.CGLIB$CALLBACK_0== null)
12     {
13       CGLIB$BIND_CALLBACKS(this);
14    
15     }
16     if(this.CGLIB$CALLBACK_0!=  null)
17     {
18       this.CGLIB$CALLBACK_0.intercept(this,SimpleBean$$EnhancerByCGLIB$$4c4a66a.CGLIB$hello$0$Method,SimpleBean$$EnhancerByCGLIB$$4c4a66a.CGLIB$emptyArgs,SimpleBean$$EnhancerByCGLIB$$4c4a66a.CGLIB$hello$0$Proxy);
19       return;
20    
21     }
22     super.hello();
23     return;
24     catch(RuntimeException  aRuntimeException2)
25     {
26       catch(Throwable  aRuntimeException2)
27       {
28         UndeclaredThrowableException JdecGenerated57 = new UndeclaredThrowableException(
29  }
30 }
31 
32 final    void CGLIB$hello$0( ) 
33  {
34     super.hello();
35     return;
36  }
37 
注: 从上面的实现代理来看,Cglib对于标识 final 关键字的class无法进行代理操作。
       对于标识final的方法,也无法进行代理
0
0
分享到:
评论

相关推荐

    Aop jdk proxy实现小例子

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

    Java JDK 实现AOP

    ### Java JDK 实现AOP详解 #### AOP的起源与发展 面向方面编程(Aspect-Oriented Programming,简称AOP)是一种编程范式,由施乐公司帕洛阿尔托研究中心(Xerox PARC)在20世纪90年代发明。AOP的初衷是为了更好地...

    AOP__使用JDK中的Proxy技术实现AOP功能

    总结来说,JDK的动态代理提供了一种轻量级的AOP实现方式,尤其适用于接口驱动的设计。通过理解其工作原理和实践,开发者可以在不修改原有代码的情况下,为应用程序添加跨切面的功能,提高代码的复用性和可维护性。

    使用JDK中的Proxy技术实现AOP功能与使用CGLIB实现AOP功能

    在Spring AOP中,如果目标对象实现了至少一个接口,那么Spring会选择使用JDK Proxy。以下是一个简单的示例: ```java public interface MyService { void doSomething(); } public class MyServiceImpl ...

    Spring_0300_JDKProxy

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

    模拟spring aop【一】基于jdk动态代理实现的aop

    本篇文章将探讨如何通过JDK动态代理实现Spring AOP的基础知识。 首先,我们要理解什么是JDK动态代理。在Java中,动态代理机制允许我们在运行时创建一个实现了特定接口的新类。这个新类的实例可以代理目标对象,执行...

    AOP_1.入门及使用JDK中的Proxy技术实现实例

    在Java领域,我们可以使用Spring框架提供的AOP支持,但本实例主要讨论的是如何使用JDK自身的动态代理(Proxy)技术来实现AOP。 JDK的Proxy类提供了创建动态代理对象的能力,这个代理对象可以代表一个或多个实现了...

    从JDK动态代理到spring AOP

    在IT领域,动态代理和AOP(面向切面编程)是两种重要的编程概念,它们能够帮助我们实现代码的解耦和模块化。本篇将详细探讨JDK动态代理和Spring AOP,以及它们在实际应用中的作用。 首先,JDK动态代理是Java提供的...

    Spring Aop的底层实现技术 --- Jdk动态代理原理

    Spring AOP 的底层实现技术 --- Jdk 动态代理原理 JDK 动态代理是 Spring AOP 的底层实现技术,允许开发者在运行期创建接口的代理实例。在 JDK 1.3 以后,JDK 动态代理技术提供了实现 AOP 的绝好底层技术。JDK 动态...

    JDK动态代理 spring aop 的原理

    总的来说,JDK动态代理是Spring AOP实现的基础,它允许我们在运行时动态创建代理对象,实现对方法调用的拦截和增强。Spring AOP则在此基础上提供了更高级的抽象,让我们可以方便地定义和管理切面,从而实现更灵活的...

    从JDK动态代理看Spring之AOP实现

    Spring的AOP实现有两种方式:JDK动态代理和CGLIB字节码代理。当目标对象实现了一个或多个接口时,Spring会选择使用JDK动态代理。以下是Spring AOP使用JDK动态代理的基本步骤: 1. **创建代理对象**:Spring会创建一...

    spring_aop之JDK的动态代理

    JDK的动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。 在Spring AOP中,当目标对象实现了至少一个接口时,Spring会使用JDK的动态代理来创建代理对象。这是因为...

    Spring AOP实现机制

    - 当目标对象实现了至少一个接口时,Spring会使用JDK的java.lang.reflect.Proxy类创建一个代理对象。 - 代理对象在调用实际方法前后,会插入相应的通知代码,从而实现AOP功能。 - **CGLIB代理**: - 如果目标...

    spring的aop实现

    JDK代理适用于接口实现类,CGLIB代理则适用于无接口或接口未被AOP通知覆盖的情况。 5. **实际应用场景**: - 日志记录:在方法调用前后记录日志信息。 - 事务管理:自动开始和提交事务,异常时回滚。 - 性能监控...

    Spring-AOP-JDK动态代理

    本篇将详细讲解Spring中的AOP实现,特别是JDK动态代理的应用。 首先,我们要了解什么是AOP(Aspect Oriented Programming,面向切面编程)。AOP是一种编程范式,旨在解决应用程序中分散的、横切关注点的问题,如...

    JavaEE JDK动态代理实现AOP切面功能

    JavaEE JDK动态代理是Java平台中实现面向切面编程(AOP)的一种方式,它允许我们在不修改原有代码的情况下,为已有对象添加额外的功能。在Java中,动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect...

    SpringIOC,DI+dynamic proxy 实现盗版AOP

    本文将深入探讨如何使用Spring的IOC和DI特性,结合动态代理(Dynamic Proxy)来实现一种类似AOP(面向切面编程)的功能,以达到在不修改原有代码的情况下增强或拦截方法调用的目的。 **一、Spring IOC(控制反转)*...

    基于Java动态代理的AOP实现.zip

    基于Java动态代理的AOP实现 项目简介 本项目旨在通过Java的动态代理技术实现面向切面编程(AOP),涵盖了静态代理、JDK动态代理、CGLIB动态代理、AspectJ以及基于instrumentation的动态代理等多种实现方式。通过...

    反射实现 AOP 动态代理模式(Spring AOP 的实现原理)

    动态代理是实现AOP的一种常用技术,它允许在运行时创建代理对象,拦截对真实对象的调用,并在调用前后添加额外的行为。 在Java开发中,反射机制是实现动态代理的关键技术之一。反射提供了在运行时访问和操作类的...

    AOP编程示例

    Spring框架提供了基于注解的AOP实现,这使得AOP的配置更为简洁。通过在切面类上定义`@Aspect`,在方法上定义`@Before`, `@After`, `@Around`等注解,可以轻松地定义切点和通知。以下是一个Spring注解AOP的例子: ``...

Global site tag (gtag.js) - Google Analytics