一:被代理的对象所要实现的接口

 package com.yeepay.testpoxy;

 import java.util.Map;

 /**
* 被动态代理的接口
* @author shangxiaofei
*
*/
public interface MyCheckPay {
/**
* 付钱的接口
* @param name
* @param money
* @return
*/
public Map<String, String> payMoney(String name,Integer money);
}

二:被动态代理的实现类

 package com.yeepay.testpoxy;

 import java.util.HashMap;
import java.util.Map; /**
* 被动态代理的实现类
* @author shangxiaofei
*
*/
public class ShangxiaofeiMyCheckPay implements MyCheckPay{ @Override
public Map<String, String> payMoney(String name, Integer money) {
System.out.println("ShangxiaofeiMyCheckPay.payMoney()========>name=["+name+"],payMoney=["+money+"]");
Map<String, String> map=new HashMap<String, String>();
map.put("result",name+"付钱"+money+"元,已经结束");
return map;
} }

三:动态代理的增强类(代理类)

 package com.yeepay.testpoxy;

 import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; /**
* 增加功能的类
* @author shangxiaofei
*
*/
public class HandlerForMyCheckPay implements InvocationHandler{
/**
* 被委托的类的引用
*/
private Object object; /**
* 空构造
*/
public HandlerForMyCheckPay() { } /**
* 有参构造
* @param object
*/
public HandlerForMyCheckPay(Object object) {
this.object = object;
} /**
* Object proxy:指代我们所代理的那个真实对象,这个对象不能使用,否则会引起栈溢出
* Method method: 指代的是我们所要调用真实对象的某个方法的Method对象
* Object[] args: 指代的是调用真实对象某个方法时接受的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable { /**
* 被代理对象调用方法之前调用(aop的前置增强)
*/
System.out.println("HandlerForMyCheckPay.invoke()=======>【付钱前】向统计系统发送付钱消息");
if(args!=null&&args.length>0){
for(int i=0;i<args.length;i++){
System.out.println("HandlerForMyCheckPay.invoke()发送消息为===>"+args[i]);
}
} /**
* 调用被代理对象的实际的方法
*/
Object d=method.invoke(this.object, args); /**
* 调用被代理对象的实际的方法之后执行:后置增强
*/
System.out.println("HandlerForMyCheckPay.invoke()=======>【付钱后】进行计算执行时长"); return d;
} }

四:代理类的生产工厂

 package com.yeepay.testpoxy;

 import java.lang.reflect.Proxy;

 /**
* 生产代理者的工厂类
* @author shangxiaofei
*
*/
public class ProxyFactory { public static MyCheckPay getMyCheckPay(){ /**
* ClassLoader loader:一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
* Class<?>[] interfaces: 一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
* InvocationHandler h:一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上
*/
Object object=Proxy.newProxyInstance(ProxyFactory.class.getClassLoader(), new Class[]{MyCheckPay.class},new HandlerForMyCheckPay(new ShangxiaofeiMyCheckPay()));
return (MyCheckPay) object;
} public static MyCheckPay getMyCheckPay2(){ /**
* ClassLoader loader:一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
* Class<?>[] interfaces: 一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
* InvocationHandler h:一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上
*/
Object object=Proxy.newProxyInstance(ProxyFactory.class.getClassLoader(),MyCheckPay.class.getInterfaces(),new HandlerForMyCheckPay(new ShangxiaofeiMyCheckPay()));
return (MyCheckPay) object;
}
}

五:测试类

 package com.yeepay.testpoxy;

 import java.util.Map;

 /**
* 测试动态代理
* @author shangxiaofei
*
*/
public class TestController { private MyCheckPay myCheckPay=ProxyFactory.getMyCheckPay(); public void payMoney(String name,Integer money){
System.out.println("TestController.payMoney(开始)");
Map<String, String> map=myCheckPay.payMoney(name, money);
System.out.println("TestController.payMoney(结束)"+map.get("result"));
} /**
* TestController.payMoney(开始)
*HandlerForMyCheckPay.invoke()=======>【付钱前】向统计系统发送付钱消息
*HandlerForMyCheckPay.invoke()发送消息为===>怪物雷克
*HandlerForMyCheckPay.invoke()发送消息为===>100
*ShangxiaofeiMyCheckPay.payMoney()========>name=[怪物雷克],payMoney=[100]
*HandlerForMyCheckPay.invoke()=======>【付钱后】进行计算执行时长
*TestController.payMoney(结束)怪物雷克付钱100元,已经结束
* @param args
*/
public static void main(String[] args) {
TestController testController=new TestController();
testController.payMoney("怪物雷克", 100);
} }

spring源码学习之【准备】jdk动态代理例子的更多相关文章

  1. Spring AOP高级——源码实现(1)动态代理技术

    在正式进入Spring AOP的源码实现前,我们需要准备一定的基础也就是面向切面编程的核心——动态代理. 动态代理实际上也是一种结构型的设计模式,JDK中已经为我们准备好了这种设计模式,不过这种JDK ...

  2. spring源码学习之路---深入AOP(终)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章和各位一起看了一下sp ...

  3. Spring 源码学习——Aop

    Spring 源码学习--Aop 什么是 AOP 以下是百度百科的解释:AOP 为 Aspect Oriented Programming 的缩写,意为:面向切面编程通过预编译的方式和运行期动态代理实 ...

  4. Spring 源码学习笔记10——Spring AOP

    Spring 源码学习笔记10--Spring AOP 参考书籍<Spring技术内幕>Spring AOP的实现章节 书有点老,但是里面一些概念还是总结比较到位 源码基于Spring-a ...

  5. Spring 源码学习笔记11——Spring事务

    Spring 源码学习笔记11--Spring事务 Spring事务是基于Spring Aop的扩展 AOP的知识参见<Spring 源码学习笔记10--Spring AOP> 图片参考了 ...

  6. Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点

    Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...

  7. spring源码学习之路---IOC初探(二)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章当中我没有提及具体的搭 ...

  8. Spring源码学习

    Spring源码学习--ClassPathXmlApplicationContext(一) spring源码学习--FileSystemXmlApplicationContext(二) spring源 ...

  9. Spring源码学习-容器BeanFactory(四) BeanDefinition的创建-自定义标签的解析.md

    写在前面 上文Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签对Spring默认标签的解析做了详解,在xml元素的解析中,Spri ...

  10. Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签

    写在前面 上文Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作中Spring对XML解析后创建了对应的Docum ...

随机推荐

  1. 利用ps指令查看某个程序的进程状态

    ps -ef是查看所有的进程,然后用grep筛选出你要的信息. eg.

  2. yum源的更新问题

    我们知道在linux下安装软件的方法有多种多样,其中利用yum的方式来安装较为简单,但需要等待的时间比较长.下面介绍一下如何更新yum的源的问题. 首先需要保证的是linux的机器能上网.然后按照下面 ...

  3. msf生成shellcode

    msfpayload windows/exec CMD = calc.exe EXITFUNC=thread C 在kali Linux2.0新版中msfpayload命令已删除,功能已集成到msfv ...

  4. unity3d基础01

    Unity3d 五大视图: 1 Scene:存放hierarchy中创建的游戏对象,但实际只能看到一部分 *Scene浏览: ①右键进入“飞行模式”,方便查看整个场景 ②选中摄像机,按ALT进入浏览的 ...

  5. hdu 2041

    ps:这道题之前一直没思路,有大神提醒我用递推,但当时没搞清...今天做了那个小蜜蜂..才懂得用递推做这道题.. 代码: #include "stdio.h"long long d ...

  6. C++语法疑点

    1函数模板不支持偏特化 2类内部的typedef 必须放在最前面,不然没法用: 疑问:为什么类声明处定义的函数体中能出现在后面在声明的成员变量??因为C++对于成员函数函数体的解析是放在整个类声明完毕 ...

  7. Redis - hash类型操作

    hash 类型操作设置操作:hset:    hset key filed value        创建指定key的filed-value名值对 hsetnx:    hsetnx key file ...

  8. 基于linux运用python开发知识点滴

    我是小白,希望我的文章能对小白们有点作用. A.Linux的开源,优势明显,如何使用,基本命令如下: 个人认为最基础的两种操作: 1.文件操作: ls 看文件夹下内容 ls -a 隐藏文件 -l非隐藏 ...

  9. Xcode Snippets

    在Double Encore,我们写的代码都是干净,可重用的——不过,有时候并不能完全做到.如在使用pragma mark的时候.下面就是一个示例:   #pragma mark - UIViewCo ...

  10. 不错的nginx文章,找个时间好好看下。

    http://blog.csdn.net/chosen0ne/article/category/915324