`

java动态代理和Cglib

阅读更多

JDK动态代理的原理是根据定义好的规则,用传入的接口创建一个新类,这就是为什么采用动态代理时为什么只能用接口引用指向代理,而不能用传入的类引用执行动态类。

cglib采用的是用创建一个继承实现类的子类,用asm库动态修改子类的代码来实现的,所以可以用传入的类引用执行代理类

动态代理

Java代码 复制代码
  1. package proxy.test;   
  2.   
  3. import java.lang.annotation.Retention;   
  4. import java.lang.annotation.RetentionPolicy;   
  5. import java.lang.reflect.InvocationHandler;   
  6. import java.lang.reflect.Method;   
  7. import java.lang.reflect.Proxy;   
  8.   
  9. /**  
  10.  * JAVA动态代理实现AOP  
  11.  *   
  12.  * from internet  
  13.  */  
  14. public class AopTest {   
  15.   
  16.     public static void main(String[] args) {   
  17.   
  18.         Before before = new Before() {   
  19.             public void before() {   
  20.                 System.out.println("...before...");   
  21.             }   
  22.         };   
  23.   
  24.         After after = new After() {   
  25.             public void after() {   
  26.                 System.out.println("...after...");   
  27.             }   
  28.         };   
  29.   
  30.         Hello hello = null;   
  31.   
  32.         // 普通方法执行   
  33.         System.out.println("-------------普通执行-------------");   
  34.         hello = new HelloEnglish();   
  35.         hello.sayHello("bao110908");   
  36.         hello.sayHi("bao110908");   
  37.         System.out.println();   
  38.   
  39.         // 切入方法执行前(前置增强)   
  40.         System.out.println("-------------前置增强-------------");   
  41.         hello = HelloAopManager.getHelloProxy(new HelloEnglish(), before);   
  42.         hello.sayHello("bao110908");   
  43.         hello.sayHi("bao110908"); // sayHi 方法没有标注 @Enhancement 所以不会进行代码切入   
  44.         System.out.println();   
  45.   
  46.         // 切入方法执行后(后置增强)   
  47.         System.out.println("-------------后置增强-------------");   
  48.         hello = HelloAopManager.getHelloProxy(new HelloEnglish(), after);   
  49.         hello.sayHello("bao110908");   
  50.         hello.sayHi("bao110908");   
  51.         System.out.println();   
  52.   
  53.         // 切入方法执行前和执行后(环绕增强)   
  54.         System.out.println("-------------环绕增强-------------");   
  55.         hello = HelloAopManager   
  56.                 .getHelloProxy(new HelloEnglish(), before, after);   
  57.         hello.sayHello("bao110908");   
  58.         hello.sayHi("bao110908");   
  59.         System.out.println();   
  60.     }   
  61. }   
  62.   
  63. @Retention(RetentionPolicy.RUNTIME)   
  64. @interface Enhancement {   
  65. }   
  66.   
  67. interface Hello {   
  68.     @Enhancement  
  69.     public void sayHello(String name);   
  70.   
  71.     public void sayHi(String name);   
  72. }   
  73.   
  74. class HelloChinese implements Hello {   
  75.     public void sayHello(String name) {   
  76.         System.out.println(name + ",您好");   
  77.     }   
  78.   
  79.     public void sayHi(String name) {   
  80.         System.out.println("哈啰," + name);   
  81.     }   
  82. }   
  83.   
  84. class HelloEnglish implements Hello {   
  85.     public void sayHello(String name) {   
  86.         System.out.println("Hello, " + name);   
  87.     }   
  88.   
  89.     public void sayHi(String name) {   
  90.         System.out.println("hi, " + name);   
  91.     }   
  92. }   
  93.   
  94. class HelloAopManager {   
  95.     private HelloAopManager() {   
  96.     }   
  97.   
  98.     public static Hello getHelloProxy(Hello hello, Before before) {   
  99.         return getHelloProxy(hello, before, null);   
  100.     }   
  101.   
  102.     public static Hello getHelloProxy(Hello hello, After after) {   
  103.         return getHelloProxy(hello, null, after);   
  104.     }   
  105.   
  106.     public static Hello getHelloProxy(Hello hello, Before before, After after) {   
  107.         HelloHandler handler = new HelloHandler();   
  108.         if (before != null) {   
  109.             handler.setBefore(before);   
  110.         }   
  111.         if (after != null) {   
  112.             handler.setAfter(after);   
  113.         }   
  114.         return handler.bind(hello);   
  115.     }   
  116. }   
  117.   
  118. /**  
  119.  * 前置增强接口  
  120.  */  
  121. interface Before {   
  122.     public void before();   
  123. }   
  124.   
  125. /**  
  126.  * 后置增强接口  
  127.  */  
  128. interface After {   
  129.     public void after();   
  130. }   
  131.   
  132. class HelloHandler implements InvocationHandler {   
  133.   
  134.     /**  
  135.      * 需要进行代理的实例  
  136.      */  
  137.     private Hello hello = null;   
  138.   
  139.     /**  
  140.      * 前置增强  
  141.      */  
  142.     private Before before = null;   
  143.   
  144.     /**  
  145.      * 后置增强  
  146.      */  
  147.     private After after = null;   
  148.   
  149.     /**  
  150.      * InvocationHandler 接口的实现方法,进行动态代理  
  151.      */  
  152.     public Object invoke(Object proxy, Method method, Object[] args)   
  153.             throws Throwable {   
  154.         // 看看接口中方法是否标注了需要 Enhancement   
  155.         boolean b = method.isAnnotationPresent(Enhancement.class);   
  156.         if (!b) {   
  157.             // 没有标注的话,按原方法执行   
  158.             return method.invoke(hello, args);   
  159.         }   
  160.         // 有标注的话,进行方法的前置和后置增强   
  161.         if (before != null) {   
  162.             before.before();   
  163.         }   
  164.         Object obj = method.invoke(hello, args);   
  165.         if (after != null) {   
  166.             after.after();   
  167.         }   
  168.         return obj;   
  169.     }   
  170.   
  171.     /**  
  172.      * 将传入的 Hello 与 InvocationHandler 进行绑定,以获得代理类的实例  
  173.      *   
  174.      * @param hello  
  175.      * @return  
  176.      */  
  177.     public Hello bind(Hello hello) {   
  178.         this.hello = hello;   
  179.         Hello helloProxy = (Hello) Proxy.newProxyInstance(hello.getClass()   
  180.                 .getClassLoader(), hello.getClass().getInterfaces(), this);// 这句用接口引用指向,不会报错。如果是实现类强制转换就会抛异常   
  181.         return helloProxy;   
  182.     }   
  183.   
  184.     public void setAfter(After after) {   
  185.         this.after = after;   
  186.     }   
  187.   
  188.     public void setBefore(Before before) {   
  189.         this.before = before;   
  190.     }   
  191. }  
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

Java代码 复制代码
  1. package proxy.test;   
  2.   
  3. import java.lang.reflect.Method;   
  4.   
  5. import net.sf.cglib.proxy.Enhancer;   
  6. import net.sf.cglib.proxy.MethodInterceptor;   
  7. import net.sf.cglib.proxy.MethodProxy;   
  8.   
  9. /**  
  10.  * 目标对象  
  11.  */  
  12. class Target {   
  13.   
  14.     public String execute() {   
  15.         String message = "----------test()----------";   
  16.         System.out.println(message);   
  17.         return message;   
  18.     }   
  19. }   
  20.   
  21. /**  
  22.  * 拦截器  
  23.  */  
  24. class MyMethodInterceptor implements MethodInterceptor {   
  25.   
  26.     public Object intercept(Object object, Method method, Object[] args,   
  27.             MethodProxy methodProxy) throws Throwable {   
  28.         System.out.println(">>>MethodInterceptor start...");   
  29.         Object result = methodProxy.invokeSuper(object, args);   
  30.         System.out.println(">>>MethodInterceptor ending...");   
  31.         return "here";   
  32.     }   
  33. }   
  34.   
  35. public class CglibTest {   
  36.     public static void main(String rags[]) {   
  37.         Target proxyTarget = (Target) createProxy(Target.class);// 强制转换为实现类,不会抛出异常   
  38.         String res = proxyTarget.execute();   
  39.         System.out.println(res);   
  40.     }   
  41.   
  42.     public static Object createProxy(Class targetClass) {   
  43.         Enhancer enhancer = new Enhancer();   
  44.         enhancer.setSuperclass(targetClass);   
  45.         enhancer.setCallback(new MyMethodInterceptor());   
  46.         return enhancer.create();   
  47.     }   
  48.   
  49. }  
分享到:
评论

相关推荐

    Java 动态代理和Cglib代理(二)

    在Java编程领域,动态代理和Cglib代理是两种常用的技术,用于在运行时创建对象的代理,以实现额外的功能,如AOP(面向切面编程)中的日志、事务管理等。本篇文章将深入探讨这两种代理机制,尤其是Cglib代理。 首先...

    java动态代理和cglib动态代理示例分享共5页.pdf

    Java动态代理和CGLIB动态代理是两种在Java开发中常用的面向切面编程(AOP)技术,主要用于在运行时创建具有额外功能的对象。这两者都允许我们在不修改原有代码的情况下,为对象添加额外的行为,如日志记录、事务管理...

    示例代码:java动态代理和cglib代理的简单例子

    Java动态代理和CGLIB代理是两种常用的在Java中实现面向切面编程(AOP)的技术,它们允许我们在不修改原有代码的情况下,为方法添加额外的功能,如日志记录、性能监控、事务管理等。本篇文章将深入探讨这两种代理机制...

    JDK动态代理和CGLIB代理

    JDK动态代理和CGLIB代理是两种常用的实现方式。 首先,我们来看看JDK动态代理。JDK动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类用于创建一个代理对象...

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

    本文将深入探讨两种主要的Java代理实现:JDK动态代理和CGLIB代理。 一、JDK动态代理 JDK动态代理基于接口实现,它要求被代理的类必须实现至少一个接口。在运行时,Java会动态地创建一个新的类,这个类实现了与原始...

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

    在Java开发中,动态代理和CGLIB代理是两种常见的面向切面编程(AOP)实现方式,它们都用于在不修改原有代码的情况下,增强或扩展对象的功能。本篇文章将深入探讨JDK动态代理和CGLIB代理的区别,以及它们在实际应用中...

    Java动态代理详解; CGLib实现动态代理1

    总结起来,Java 动态代理和 CGLib 是 Java 中实现代理模式的重要工具。动态代理提供了在运行时动态创建代理对象的能力,而 CGLib 使得代理机制可以应用于没有接口的类,提高了代码的灵活性和可扩展性。通过代理模式...

    Jdk动态代理和cglib动态代理原理

    动态代理主要分为两种技术:JDK动态代理和CGLIB动态代理。 ### JDK动态代理 JDK动态代理是Java内置的一种机制,依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。以下是JDK动态...

    动态代理和cglib例子

    动态代理和CGLIB在Java开发中扮演着重要的角色,特别是在实现面向切面编程(AOP)和增强对象功能方面。动态代理允许我们在不修改原始代码的情况下,为已有对象添加额外的功能,比如日志记录、性能监控等。而CGLIB...

    Java JDK代理、CGLIB、AspectJ代理分析比较

    ### Java代理技术详解:JDK代理、CGLIB与AspectJ #### 一、代理模式简介 代理模式是一种常见的设计模式,在《Design Patterns in Java》一书中对其有明确的定义:“代理模式为一个对象提供一个代理,以控制对该...

    Java 动态代理详解(代理模式+静态代理+JDK动态代理+CGLIB动态代理)

    Java 动态代理详解(代理模式+静态代理+JDK动态代理+CGLIB动态代理) Java 动态代理是 Java 编程语言中的一种强大工具,广泛应用于 Spring AOP、Hibernate 数据查询、测试框架的后端 mock、RPC 远程调用、Java 注解...

    Spring框架中JDK动态代理和cglib动态代理

    Spring 框架中 JDK 动态代理和 CGLIB 动态代理是 Spring AOP 中一个非常重要的知识点。Spring AOP 框架会根据实际情况选择使用 JDK 的动态代理还是 CGLIB 的动态代理。 JDK 动态代理是 Java 自带的动态代理机制,它...

    java动态代理实例(jdk动态代理和cglib)

    本篇将深入探讨两种主要的Java动态代理技术:JDK动态代理和CGLIB。 首先,我们来了解一下JDK动态代理。JDK动态代理基于Java反射API实现,主要用于接口代理。以下是一个简单的JDK动态代理的使用步骤: 1. **定义...

    JAVA动态代理实现Demo(JDK动态代理和CGLIB动态代理)

    Java提供了两种主要的动态代理实现方式:JDK动态代理和CGLIB动态代理。 **JDK动态代理**: JDK动态代理基于接口实现,也就是说,被代理的对象必须实现至少一个接口。代理机制的核心是`java.lang.reflect.Proxy`类和...

    AOP之JDK动态代理和CGLib动态代理

    Spring框架是AOP实现的一个典范,它提供了两种主要的动态代理方式:JDK动态代理和CGLib动态代理。 **JDK动态代理**: JDK动态代理基于Java的反射API实现,适用于接口代理。当目标对象实现了至少一个接口时,Spring...

    Java动态代理Proxy和cglib

    总结,Java的动态代理和CGLIB都是强大的工具,它们允许开发者在运行时扩展或修改对象的行为。选择哪个取决于具体的应用场景和需求,如是否需要接口、性能要求以及是否需要对非接口类进行代理。通过熟练掌握这两者,...

    JAVA JDK静态代理、动态代理、CGlib代理的代码演示

    Java提供了两种主要的代理实现方式:JDK静态代理和动态代理,另外还有第三方库如CGlib提供的代理实现。下面我们将详细探讨这些代理技术,并通过代码演示来理解它们的工作原理。 ### 1. JDK静态代理 静态代理是我们...

    Java动态代理CGlib Jar包

    CGLIB是一个强大的、高性能的代码生成库。它被广泛使用在基于代理的AOP框架(例如Spring AOP和...EasyMock和jMock作为流行的Java测试库,它们提供Mock对象的方式来支持测试,都使用了CGLIB来对没有接口的类进行代理。

    Jdk动态代理,cglib动态代理,反射和拦截器(链)示例

    Java中的动态代理、反射和...总之,理解和掌握JDK动态代理、CGLIB动态代理、反射和拦截器是提升Java开发技能的关键步骤。通过实际操作这些示例,你将能够更好地应用这些技术到实际项目中,提高代码的灵活性和可维护性。

    Java动态代理(JDK和cglib)

    2. **CGLIB动态代理** - 基于继承实现的动态代理。 **JDK动态代理实现:** JDK动态代理主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。`Proxy`类提供了创建动态代理类的方法...

Global site tag (gtag.js) - Google Analytics