Spring之动态代理两种实现

基于jdk实现的动态代理

 1 package com.proxy.daili;
 2
 3 import com.proxy.daili.service.IModelMath;
 4
 5 import java.lang.reflect.InvocationHandler;
 6 import java.lang.reflect.Method;
 7 import java.lang.reflect.Proxy;
 8 import java.util.Arrays;
 9
10 /**
11  * 动态代理模式类
12  * 第一种代理模式:Jdk动态代理
13  *      注意:实现InvocationHandler这个接口
14  *
15  *      基于接口的
16  */
17 public class JdkDynamicProxy implements InvocationHandler {
18
19     //定义需要代理的接口
20     protected IModelMath iModelMath;
21
22     //将需要代理的接口作为参数传入到动态代理设计模式类中
23     public JdkDynamicProxy(IModelMath iModelMath){
24         this.iModelMath = iModelMath;
25     }
26
27     /**
28      * 生成代理对象
29      * 使用java.lang.reflect.Proxy这个类调用newProxyInstance方法
30      * 返回 动态代理类对象
31      */
32     public IModelMath iModelMathmethod(){
33         IModelMath iModelMathProxy = (IModelMath) Proxy.newProxyInstance(iModelMath.getClass().getClassLoader(),
34                 iModelMath.getClass().getInterfaces(),
35                 this);
36         return iModelMathProxy;
37     }
38
39     /**
40      * 开始做代理的操作
41      * Object proxy 代理对象的引用
42      * Method method 当前执行的方法
43      * Object[] args  当前执行方法的参数
44      * 返回  与被代理对象返回的值相同
45      */
46     @Override
47     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
48         System.out.println("你调用的方法为:"+method.getName());
49         System.out.println("你调用的方法参数有:"+ Arrays.toString(args));
50         Object invoke = method.invoke(iModelMath, args);
51         System.out.println("方法的返回数据:"+invoke);
52         return invoke;
53     }
54
55 }

 1 package com.proxy.test;
 2
 3 import com.proxy.daili.service.IModelMath;
 4 import com.proxy.daili.JdkDynamicProxy;
 5 import com.proxy.daili.service.ModelMath;
 6 import org.junit.Test;
 7
 8 public class TestJDKDynamicProxy {
 9
10     /**
11      * 使用jdk方式的动态代理
12      * 测试
13      */
14     @Test
15     public void testJdkDynamicProxy(){
16         //需要被代理的动态对象
17         IModelMath imm = new ModelMath();
18         //代理对象
19         IModelMath math = new JdkDynamicProxy(imm).iModelMathmethod();
20         //通过代理对象做操作
21         int addition = math.addition(10, 2);
22         int subtraction = math.subtraction(20, 19);
23         System.out.println("实际方法的数据为:"+addition);
24         System.out.println("实际方法的数据为:"+subtraction);
25     }
26 }

基于gcLib实现的动态代理

 1 package com.proxy.daili;
 2
 3 import com.proxy.daili.service.IModelMath;
 4 import com.proxy.daili.service.ModelMath;
 5 import net.sf.cglib.proxy.Enhancer;
 6 import net.sf.cglib.proxy.MethodInterceptor;
 7 import net.sf.cglib.proxy.MethodProxy;
 8
 9 import java.lang.reflect.Method;
10 import java.util.Arrays;
11
12 /**
13  * cglib动态代理设计类
14  *  前提必须要先导入 cglib  包
15  *  基于 实现类的
16  */
17 public class CglibDynamicProxy implements MethodInterceptor {
18
19     //定义被代理的实现类(注意这   是实现类,不是接口)
20     private ModelMath modelMath;
21
22     //将被代理的对象作为参数  传入到 cglib动态代理设计类中
23     public CglibDynamicProxy(ModelMath modelMath){
24         this.modelMath = modelMath;
25     }
26
27     //生成代理对象
28     public ModelMath getProxyModelMath(){
29         //new 一个Enhancer对象
30         Enhancer enhancer = new Enhancer();
31         //指定他的父类(注意这   是实现类,不是接口)
32         enhancer.setSuperclass(ModelMath.class);
33         //指定真正做事情的回调方法
34         enhancer.setCallback(this);
35         //生成代理类对象
36         ModelMath o = (ModelMath) enhancer.create();
37         //返回
38         return o;
39     }
40
41     /**
42      * 执行被代理的任何方法,都会经过这个方法
43      * @param o
44      * @param method
45      * @param objects
46      * @param methodProxy
47      * @return
48      * @throws Throwable
49      */
50     @Override
51     public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
52         System.out.println("通过gclib 动态代理调用的方法名为:"+method.getName());
53         System.out.println("通过gclib 动态代理调用的方法的参数包含:"+ Arrays.toString(objects));
54         Object invoke = method.invoke(modelMath, objects);
55         System.out.println("通过gclib 动态代理调用的方法返回的数据:"+ invoke);
56         return invoke;
57     }
58 }

 1 package com.proxy.test;
 2
 3 import com.proxy.daili.CglibDynamicProxy;
 4 import com.proxy.daili.service.ModelMath;
 5 import org.junit.Test;
 6
 7 public class TestCgLibDynamicProxy {
 8     /**
 9      * 使用gclib方式的动态代理
10      * 测试
11      */
12     @Test
13     public void testCglibDynamicProxy(){
14         ModelMath modelMath = new ModelMath();
15         ModelMath proxyModelMath = new CglibDynamicProxy(modelMath).getProxyModelMath();
16         int subtraction = proxyModelMath.subtraction(1, 44);
17         int addition = proxyModelMath.addition(10, -1);
18         System.out.println("执行减法得到的正式数据为:"+subtraction);
19         System.out.println("执行加法得到的正式数据为:"+addition);
20     }
21 }

原文地址:https://www.cnblogs.com/in-the-game-of-thrones/p/11474069.html

时间: 2024-09-30 20:42:00

Spring之动态代理两种实现的相关文章

Spring定时器配置的两种实现方式OpenSymphony Quartz和java Timer详解

原创整理不易,转载请注明出处:Spring定时器配置的两种实现方式OpenSymphony Quartz和java Timer详解 代码下载地址:http://www.zuidaima.com/share/1772648445103104.htm 有两种流行Spring定时器配置:Java的Timer类和OpenSymphony的Quartz. 1.Java Timer定时 首先继承java.util.TimerTask类实现run方法 import java.util.TimerTask; p

spring配置属性的两种方式

spring配置属性有两种方式,第一种方式通过context命名空间中的property-placeholder标签 <context:property-placeholder location="classpath:jdbctemplate/jdbc.properties" /> 第二种方式通过创建bean,对应类为PropertyPlaceholderConfigurer <bean id="propertyConfigurer" class=

spring实现定时任务的两种方式

? Java? 方式一:注解 1.在spring配置文件中加入task的命名空间 123 xmlns:task="http://www.springframework.org/schema/task" http:http://www.springframework.org/schema/task/spring-task-3.0.xsd 2.配置扫描注解 12 <task:annotation-driven /><context:component-scan base-

Spring中AOP的两种代理方式(Java动态代理和CGLIB代理)

第一种代理即Java的动态代理方式上一篇已经分析,在这里不再介绍,现在我们先来了解下GCLIB代理是什么?它又是怎样实现的?和Java动态代理有什么区别? cglib(Code Generation Library)是一个强大的,高性能,高质量的Code生成类库.它可以在运行期扩展Java类与实现Java接口. cglib封装了asm,可以在运行期动态生成新的class. cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制. 原理区别: java动态代理是利用反射机

spring aop 动态代理批量调用方法实例

今天项目经理发下任务,需要测试 20 个接口,看看推送和接收数据是否正常.因为对接传输的数据是 xml 格式的字符串,所以我拿现成的数据,先生成推送过去的数据并存储到文本,以便验证数据是否正确,这时候要批量调用这些同名方法,我觉得这里可以发展成有潜力的代码. 推送比较好做数据,队友们都写好代码,但是有个问题,方法要的值都大致相同,封装的方式不一致,多人开发,有的封装对象里面,有的直接使用 Map.get(),唉,一千个人一千个哈姆雷特嘛,只好利用反射和动态代理节省自己的代码量,而且这种方式练练手

WebServcie结合Spring结合动态代理进行抽象封装以及性能优化

webService抽象客户端封装.动态代理提升使用性能 1. 什么是webService webService就是在web上提供非相关系统与系统之间进行数据交互的一种服务.通过实现定义好的wsdl借口配置文件,进行约定以及调用. 在企业的内部系统中很常见,尤其是比较大型的企业,有数十种内部使用的系统,之间的通信基本上都是使用webService. 通俗点说就是:你要调用别人的服务,你就通过wsdl生成客户端代码,方便进行直接调用. 你需要被别人调用,你就通过wsdl生成服务端代码,方便对方系统

Spring AOP动态代理实现,解决Spring Boot中无法正常启用JDK动态代理的问题

Spring AOP底层的动态代理实现有两种方式:一种是JDK动态代理,另一种是CGLib动态代理. JDK动态代理 JDK 1.3版本以后提供了动态代理,允许开发者在运行期创建接口的代理实例,而且只能为接口创建代理实例. 如果被代理目标没有接口那么Spring也无能为力,Spring通过Java的反射机制生成被代理接口的新的匿名实现类. JDK动态代理具体实现原理: 通过实现InvocationHandlet接口创建自己的调用处理器: 通过为Proxy类指定ClassLoader对象和一组in

spring 中常用的两种事务配置方式以及事务的传播性、隔离级别

转载:http://blog.csdn.net/qh_java/article/details/51811533 一.注解式事务 1.注解式事务在平时的开发中使用的挺多,工作的两个公司中看到很多项目使用了这种方式,下面看看具体的配置demo. 2.事务配置实例 (1).spring+mybatis 事务配置 [html] view plain copy <!-- 定义事务管理器 --> <bean id="transactionManager" class="

详解 spring AOP 动态代理

通过例子查看,首先建立一个实现动态代理的接口Interface1.java,代码如下: package my.spring.fuck.aoptest; public interface Interface1 { public void say_hello(); } 很简单的一个接口,然后定义一个这个接口的实现类MyImple.java,代码: package my.spring.fuck.aoptest; public class MyImple implements Interface1{ @