- 浏览: 121477 次
- 性别:
- 来自: 北京
-
文章分类
最新评论
-
maoghj:
dom4j API转载 -
hongdong1017:
[url][/url][flash=200,200][/fla ...
linux下如何执行.sh文件 -
hongdong1017:
[b][/b][i][/i][u][/u]引用
linux下如何执行.sh文件 -
shangfengying:
...
java web项目中web.xml的一点东西 -
12345678:
谢谢 ~ 我用的~Jon Galloway~~的
java项目清除svn信息
JDK动态代理的原理是根据定义好的规则,用传入的接口创建一个新类,这就是为什么采用动态代理时为什么只能用接口引用指向代理,而不能用传入的类引用执行动态类。
cglib采用的是用创建一个继承实现类的子类,用asm库动态修改子类的代码来实现的,所以可以用传入的类引用执行代理类
动态代理
- package proxy.test;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- /**
- * JAVA动态代理实现AOP
- *
- * from internet
- */
- public class AopTest {
- public static void main(String[] args) {
- Before before = new Before() {
- public void before() {
- System.out.println("...before...");
- }
- };
- After after = new After() {
- public void after() {
- System.out.println("...after...");
- }
- };
- Hello hello = null;
- // 普通方法执行
- System.out.println("-------------普通执行-------------");
- hello = new HelloEnglish();
- hello.sayHello("bao110908");
- hello.sayHi("bao110908");
- System.out.println();
- // 切入方法执行前(前置增强)
- System.out.println("-------------前置增强-------------");
- hello = HelloAopManager.getHelloProxy(new HelloEnglish(), before);
- hello.sayHello("bao110908");
- hello.sayHi("bao110908"); // sayHi 方法没有标注 @Enhancement 所以不会进行代码切入
- System.out.println();
- // 切入方法执行后(后置增强)
- System.out.println("-------------后置增强-------------");
- hello = HelloAopManager.getHelloProxy(new HelloEnglish(), after);
- hello.sayHello("bao110908");
- hello.sayHi("bao110908");
- System.out.println();
- // 切入方法执行前和执行后(环绕增强)
- System.out.println("-------------环绕增强-------------");
- hello = HelloAopManager
- .getHelloProxy(new HelloEnglish(), before, after);
- hello.sayHello("bao110908");
- hello.sayHi("bao110908");
- System.out.println();
- }
- }
- @Retention(RetentionPolicy.RUNTIME)
- @interface Enhancement {
- }
- interface Hello {
- @Enhancement
- public void sayHello(String name);
- public void sayHi(String name);
- }
- class HelloChinese implements Hello {
- public void sayHello(String name) {
- System.out.println(name + ",您好");
- }
- public void sayHi(String name) {
- System.out.println("哈啰," + name);
- }
- }
- class HelloEnglish implements Hello {
- public void sayHello(String name) {
- System.out.println("Hello, " + name);
- }
- public void sayHi(String name) {
- System.out.println("hi, " + name);
- }
- }
- class HelloAopManager {
- private HelloAopManager() {
- }
- public static Hello getHelloProxy(Hello hello, Before before) {
- return getHelloProxy(hello, before, null);
- }
- public static Hello getHelloProxy(Hello hello, After after) {
- return getHelloProxy(hello, null, after);
- }
- public static Hello getHelloProxy(Hello hello, Before before, After after) {
- HelloHandler handler = new HelloHandler();
- if (before != null) {
- handler.setBefore(before);
- }
- if (after != null) {
- handler.setAfter(after);
- }
- return handler.bind(hello);
- }
- }
- /**
- * 前置增强接口
- */
- interface Before {
- public void before();
- }
- /**
- * 后置增强接口
- */
- interface After {
- public void after();
- }
- class HelloHandler implements InvocationHandler {
- /**
- * 需要进行代理的实例
- */
- private Hello hello = null;
- /**
- * 前置增强
- */
- private Before before = null;
- /**
- * 后置增强
- */
- private After after = null;
- /**
- * InvocationHandler 接口的实现方法,进行动态代理
- */
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- // 看看接口中方法是否标注了需要 Enhancement
- boolean b = method.isAnnotationPresent(Enhancement.class);
- if (!b) {
- // 没有标注的话,按原方法执行
- return method.invoke(hello, args);
- }
- // 有标注的话,进行方法的前置和后置增强
- if (before != null) {
- before.before();
- }
- Object obj = method.invoke(hello, args);
- if (after != null) {
- after.after();
- }
- return obj;
- }
- /**
- * 将传入的 Hello 与 InvocationHandler 进行绑定,以获得代理类的实例
- *
- * @param hello
- * @return
- */
- public Hello bind(Hello hello) {
- this.hello = hello;
- Hello helloProxy = (Hello) Proxy.newProxyInstance(hello.getClass()
- .getClassLoader(), hello.getClass().getInterfaces(), this);// 这句用接口引用指向,不会报错。如果是实现类强制转换就会抛异常
- return helloProxy;
- }
- public void setAfter(After after) {
- this.after = after;
- }
- public void setBefore(Before before) {
- this.before = before;
- }
- }
package proxy.test; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * JAVA动态代理实现AOP * * from internet */ public class AopTest { public static void main(String[] args) { Before before = new Before() { public void before() { System.out.println("...before..."); } }; After after = new After() { public void after() { System.out.println("...after..."); } }; Hello hello = null; // 普通方法执行 System.out.println("-------------普通执行-------------"); hello = new HelloEnglish(); hello.sayHello("bao110908"); hello.sayHi("bao110908"); System.out.println(); // 切入方法执行前(前置增强) System.out.println("-------------前置增强-------------"); hello = HelloAopManager.getHelloProxy(new HelloEnglish(), before); hello.sayHello("bao110908"); hello.sayHi("bao110908"); // sayHi 方法没有标注 @Enhancement 所以不会进行代码切入 System.out.println(); // 切入方法执行后(后置增强) System.out.println("-------------后置增强-------------"); hello = HelloAopManager.getHelloProxy(new HelloEnglish(), after); hello.sayHello("bao110908"); hello.sayHi("bao110908"); System.out.println(); // 切入方法执行前和执行后(环绕增强) System.out.println("-------------环绕增强-------------"); hello = HelloAopManager .getHelloProxy(new HelloEnglish(), before, after); hello.sayHello("bao110908"); hello.sayHi("bao110908"); System.out.println(); } } @Retention(RetentionPolicy.RUNTIME) @interface Enhancement { } interface Hello { @Enhancement public void sayHello(String name); public void sayHi(String name); } class HelloChinese implements Hello { public void sayHello(String name) { System.out.println(name + ",您好"); } public void sayHi(String name) { System.out.println("哈啰," + name); } } class HelloEnglish implements Hello { public void sayHello(String name) { System.out.println("Hello, " + name); } public void sayHi(String name) { System.out.println("hi, " + name); } } class HelloAopManager { private HelloAopManager() { } public static Hello getHelloProxy(Hello hello, Before before) { return getHelloProxy(hello, before, null); } public static Hello getHelloProxy(Hello hello, After after) { return getHelloProxy(hello, null, after); } public static Hello getHelloProxy(Hello hello, Before before, After after) { HelloHandler handler = new HelloHandler(); if (before != null) { handler.setBefore(before); } if (after != null) { handler.setAfter(after); } return handler.bind(hello); } } /** * 前置增强接口 */ interface Before { public void before(); } /** * 后置增强接口 */ interface After { public void after(); } class HelloHandler implements InvocationHandler { /** * 需要进行代理的实例 */ private Hello hello = null; /** * 前置增强 */ private Before before = null; /** * 后置增强 */ private After after = null; /** * InvocationHandler 接口的实现方法,进行动态代理 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 看看接口中方法是否标注了需要 Enhancement boolean b = method.isAnnotationPresent(Enhancement.class); if (!b) { // 没有标注的话,按原方法执行 return method.invoke(hello, args); } // 有标注的话,进行方法的前置和后置增强 if (before != null) { before.before(); } Object obj = method.invoke(hello, args); if (after != null) { after.after(); } return obj; } /** * 将传入的 Hello 与 InvocationHandler 进行绑定,以获得代理类的实例 * * @param hello * @return */ public Hello bind(Hello hello) { this.hello = hello; Hello helloProxy = (Hello) Proxy.newProxyInstance(hello.getClass() .getClassLoader(), hello.getClass().getInterfaces(), this);// 这句用接口引用指向,不会报错。如果是实现类强制转换就会抛异常 return helloProxy; } public void setAfter(After after) { this.after = after; } public void setBefore(Before before) { this.before = before; } }
CGLIB
- package proxy.test;
- import java.lang.reflect.Method;
- import net.sf.cglib.proxy.Enhancer;
- import net.sf.cglib.proxy.MethodInterceptor;
- import net.sf.cglib.proxy.MethodProxy;
- /**
- * 目标对象
- */
- class Target {
- public String execute() {
- String message = "----------test()----------";
- System.out.println(message);
- return message;
- }
- }
- /**
- * 拦截器
- */
- class MyMethodInterceptor implements MethodInterceptor {
- public Object intercept(Object object, Method method, Object[] args,
- MethodProxy methodProxy) throws Throwable {
- System.out.println(">>>MethodInterceptor start...");
- Object result = methodProxy.invokeSuper(object, args);
- System.out.println(">>>MethodInterceptor ending...");
- return "here";
- }
- }
- public class CglibTest {
- public static void main(String rags[]) {
- Target proxyTarget = (Target) createProxy(Target.class);// 强制转换为实现类,不会抛出异常
- String res = proxyTarget.execute();
- System.out.println(res);
- }
- public static Object createProxy(Class targetClass) {
- Enhancer enhancer = new Enhancer();
- enhancer.setSuperclass(targetClass);
- enhancer.setCallback(new MyMethodInterceptor());
- return enhancer.create();
- }
- }
发表评论
-
js三种声明方式
2013-05-02 10:08 978JS中声明函数大体上有 ... -
正则表达式学习(转)
2013-03-11 09:54 794deerchao的blog Be and awar ... -
dom4j API转载
2013-03-04 10:43 1021功能简介 dom4j是一个Java的XML ... -
java 使用相对路径读取文件
2013-03-04 10:41 764java 使用相对路径读取 ... -
STRING INT INTEGER间的转换(转载)
2013-03-04 10:37 1111http://hanric.spaces.live.com/ ... -
java异常总结(转)
2013-02-27 09:02 1161java中异常小结 2010-07-03 1 ... -
Xml中SelectSingleNode用法详解(转)
2013-02-27 09:01 1087最常见的XML数据类型有:Element, Attribute ... -
xml报文编写以及解析
2013-02-25 16:30 1366// 封装电子保单回执报文 Document docum ... -
jdbc手动控制事务
2013-02-24 09:37 924在JavaBean数据库操作中,一项事务是指由一条或多条对数 ... -
JMS简介
2011-06-07 09:46 8741. JMS基本概念 JMS(Java Message S ... -
数据库连接池的实现方式
2010-12-25 10:18 1151转贴 查看文章 ... -
SVN基本操作之新手上路
2010-12-23 10:16 870SVN是什么Svn是一个离 ... -
java代理模式以及动态代理详解
2010-12-10 11:15 1212本文讲述代理模式... 代理模式的作用是:为其他对象提供一种 ... -
java静态方法和静态代码块
2010-12-09 16:50 976java 静态代码块 静态方法区别 一般情况下,如果有些代码必 ... -
JAVA 注解示例 详解
2010-12-09 12:57 669转自步行者 注解(Annotation) 为我们在代 ... -
Java泛型
2010-12-09 11:58 847泛型是Java SE 1.5的新特性,泛型的本质是参数化类型, ... -
Java事件处理机制- 事件监听器的四种实现方式
2010-11-26 15:58 1667转自http://wcily123.iteye.com/bl ... -
java线程的一点东西
2010-11-08 18:50 778转自 英特尔® 软件网络 ...
相关推荐
在Java编程领域,动态代理和Cglib代理是两种常用的技术,用于在运行时创建对象的代理,以实现额外的功能,如AOP(面向切面编程)中的日志、事务管理等。本篇文章将深入探讨这两种代理机制,尤其是Cglib代理。 首先...
Java动态代理和CGLIB动态代理是两种在Java开发中常用的面向切面编程(AOP)技术,主要用于在运行时创建具有额外功能的对象。这两者都允许我们在不修改原有代码的情况下,为对象添加额外的行为,如日志记录、事务管理...
Java动态代理和CGLIB代理是两种常用的在Java中实现面向切面编程(AOP)的技术,它们允许我们在不修改原有代码的情况下,为方法添加额外的功能,如日志记录、性能监控、事务管理等。本篇文章将深入探讨这两种代理机制...
JDK动态代理和CGLIB代理是两种常用的实现方式。 首先,我们来看看JDK动态代理。JDK动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类用于创建一个代理对象...
本文将深入探讨两种主要的Java代理实现:JDK动态代理和CGLIB代理。 一、JDK动态代理 JDK动态代理基于接口实现,它要求被代理的类必须实现至少一个接口。在运行时,Java会动态地创建一个新的类,这个类实现了与原始...
在Java开发中,动态代理和CGLIB代理是两种常见的面向切面编程(AOP)实现方式,它们都用于在不修改原有代码的情况下,增强或扩展对象的功能。本篇文章将深入探讨JDK动态代理和CGLIB代理的区别,以及它们在实际应用中...
总结起来,Java 动态代理和 CGLib 是 Java 中实现代理模式的重要工具。动态代理提供了在运行时动态创建代理对象的能力,而 CGLib 使得代理机制可以应用于没有接口的类,提高了代码的灵活性和可扩展性。通过代理模式...
动态代理主要分为两种技术:JDK动态代理和CGLIB动态代理。 ### JDK动态代理 JDK动态代理是Java内置的一种机制,依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。以下是JDK动态...
动态代理和CGLIB在Java开发中扮演着重要的角色,特别是在实现面向切面编程(AOP)和增强对象功能方面。动态代理允许我们在不修改原始代码的情况下,为已有对象添加额外的功能,比如日志记录、性能监控等。而CGLIB...
### Java代理技术详解:JDK代理、CGLIB与AspectJ #### 一、代理模式简介 代理模式是一种常见的设计模式,在《Design Patterns in Java》一书中对其有明确的定义:“代理模式为一个对象提供一个代理,以控制对该...
Java 动态代理详解(代理模式+静态代理+JDK动态代理+CGLIB动态代理) Java 动态代理是 Java 编程语言中的一种强大工具,广泛应用于 Spring AOP、Hibernate 数据查询、测试框架的后端 mock、RPC 远程调用、Java 注解...
Spring 框架中 JDK 动态代理和 CGLIB 动态代理是 Spring AOP 中一个非常重要的知识点。Spring AOP 框架会根据实际情况选择使用 JDK 的动态代理还是 CGLIB 的动态代理。 JDK 动态代理是 Java 自带的动态代理机制,它...
本篇将深入探讨两种主要的Java动态代理技术:JDK动态代理和CGLIB。 首先,我们来了解一下JDK动态代理。JDK动态代理基于Java反射API实现,主要用于接口代理。以下是一个简单的JDK动态代理的使用步骤: 1. **定义...
Java提供了两种主要的动态代理实现方式:JDK动态代理和CGLIB动态代理。 **JDK动态代理**: JDK动态代理基于接口实现,也就是说,被代理的对象必须实现至少一个接口。代理机制的核心是`java.lang.reflect.Proxy`类和...
Spring框架是AOP实现的一个典范,它提供了两种主要的动态代理方式:JDK动态代理和CGLib动态代理。 **JDK动态代理**: JDK动态代理基于Java的反射API实现,适用于接口代理。当目标对象实现了至少一个接口时,Spring...
总结,Java的动态代理和CGLIB都是强大的工具,它们允许开发者在运行时扩展或修改对象的行为。选择哪个取决于具体的应用场景和需求,如是否需要接口、性能要求以及是否需要对非接口类进行代理。通过熟练掌握这两者,...
Java提供了两种主要的代理实现方式:JDK静态代理和动态代理,另外还有第三方库如CGlib提供的代理实现。下面我们将详细探讨这些代理技术,并通过代码演示来理解它们的工作原理。 ### 1. JDK静态代理 静态代理是我们...
CGLIB是一个强大的、高性能的代码生成库。它被广泛使用在基于代理的AOP框架(例如Spring AOP和...EasyMock和jMock作为流行的Java测试库,它们提供Mock对象的方式来支持测试,都使用了CGLIB来对没有接口的类进行代理。
Java中的动态代理、反射和...总之,理解和掌握JDK动态代理、CGLIB动态代理、反射和拦截器是提升Java开发技能的关键步骤。通过实际操作这些示例,你将能够更好地应用这些技术到实际项目中,提高代码的灵活性和可维护性。
2. **CGLIB动态代理** - 基于继承实现的动态代理。 **JDK动态代理实现:** JDK动态代理主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。`Proxy`类提供了创建动态代理类的方法...