动态代理,有两种情况,第一种是有接口的情况下,你可以选择为jdk自带的动态代理的方式来编写程序,但你想要为一个实在的类编写动态代理的方式的话,这时候就必须选择一些开源的lib包,如cglib包,同时还需要asm包。 
cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制。

第一种通过jdk的动态代理(必须接口): 
主类(实现主要方法的类)接口:

  1. package bean;
  2. public interface TestInter {
  3. public void save();
  4. }
  5. 具体类:
  6. package bean;
  7. public class TestClass implements TestInter{
  8. public void save(){
  9. System.out.println("调用TestClass.save()");
  10. }
  11. }

代理类:

  1. package bean;
  2. import java.lang.reflect.InvocationHandler;
  3. import java.lang.reflect.Method;
  4. import java.lang.reflect.Proxy;
  5. import org.apache.log4j.Logger;
  6. public class Test implements InvocationHandler {
  7. private Object originalObject;
  8. public Object bind(Object obj) {
  9. System.out.println("coming here...");
  10. this.originalObject = obj;
  11. return Proxy.newProxyInstance(
  12. obj.getClass().getClassLoader(),
  13. obj.getClass().getInterfaces(),this
  14. );
  15. }
  16. /**
  17. * 反射?
  18. */
  19. public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
  20. Object result=null;
  21. if(arg1.getName().startsWith("save")){
  22. System.out.println("start...");
  23. result=arg1.invoke(this.originalObject,arg2);
  24. System.out.println("end...");
  25. }
  26. return result;
  27. }
  28. }

测试类:

  1. package bean;
  2. public class TestMain {
  3. /**
  4. * @param args
  5. */
  6. public static void main(String[] args) {
  7. Test test=new Test();
  8. TestClass tc=new TestClass();
  9. try{
  10. ((TestInter)test.bind(tc)).save();
  11. }catch(Exception e){
  12. System.out.println(e.getMessage());
  13. e.printStackTrace();
  14. }
  15. }
  16. }

运行结果:

  1. coming here...
  2. start...
  3. 调用TestClass.save()
  4. end...

第二种方法:

主类(实现主要方法的类):

  1. package cglib;
  2. public class TestClass {
  3. public void save(){
  4. System.out.println("调用TestClass.save()");
  5. }
  6. }

拦截器类(实现功能的地方):

  1. package cglib;
  2. import java.lang.reflect.Method;
  3. import net.sf.cglib.proxy.MethodInterceptor;
  4. import net.sf.cglib.proxy.MethodProxy;
  5. /**
  6. * 实现接口MethodInterceptor
  7. */
  8. public class MyMethodInterceptor implements MethodInterceptor {
  9. /**
  10. * 拦截器,在这里实现需要的功能
  11. * 在这里仅仅是在执行之前打印了start 在执行之后打印了end
  12. */
  13. public Object intercept(Object arg0, Method arg1, Object[] arg2,
  14. MethodProxy arg3) throws Throwable {
  15. System.out.println("start...");
  16. Object result = arg3.invokeSuper(arg0,arg2);
  17. System.out.println("ending...");
  18. return result;
  19. }
  20. }

创建代理的类:

  1. package cglib;
  2. import net.sf.cglib.proxy.Enhancer;
  3. public class TestProxy {
  4. /**
  5. * 创建代理类
  6. * @param targetClass
  7. * @return
  8. */
  9. public Object createProxy(Class targetClass){
  10. Enhancer enhancer = new Enhancer();
  11. //设定父类???
  12. enhancer.setSuperclass(targetClass);
  13. //这里貌似是进行回调,主要的操作被放进了MyMethodInterceptor类里
  14. enhancer.setCallback(new MyMethodInterceptor());
  15. return enhancer.create();
  16. }
  17. }

测试类

  1. package cglib;
  2. public class TestMain {
  3. /**
  4. * 测试类
  5. * @param args
  6. */
  7. public static void main(String[] args) {
  8. TestClass tc=new TestClass();
  9. TestProxy tp=new TestProxy();
  10. TestClass tcp=(TestClass)tp.createProxy(tc.getClass());
  11. tcp.save();
  12. }
  13. }

运行结果:

    1. start...
    2. 调用TestClass.save()
    3. ending...

java动态代理的两种方法的更多相关文章

  1. Java动态代理的两种实现方法

    注:文章转载自:https://blog.csdn.net/m0_38039437/article/details/77970633 一.代理的概念 动态代理技术是整个java技术中最重要的一个技术, ...

  2. Java动态代理的两种实现方式:

    方式一:传统的代理 package cn.hc.domain; import java.lang.reflect.InvocationHandler; import java.lang.reflect ...

  3. 动态代理的两种实现方式(JDK/Cglib)

    =========================================== 原文链接: 动态代理的两种实现方式(JDK/Cglib) 转载请注明出处! ================== ...

  4. 动态代理的两种方式,以及区别(静态代理、JDK与CGLIB动态代理、AOP+IoC)

    Spring学习总结(二)——静态代理.JDK与CGLIB动态代理.AOP+IoC   目录 一.为什么需要代理模式 二.静态代理 三.动态代理,使用JDK内置的Proxy实现 四.动态代理,使用cg ...

  5. SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法

    软件152 尹以操 首先谢谢大佬的简书文章:http://www.jianshu.com/p/45ad65690e33# 这篇文章中讲的是spring中使用spring data jpa,使用了xml ...

  6. Java 创建线程的两种方法

    Java提供了线程类Thread来创建多线程的程序.其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象.每个Thread对象描述了一个单独的线程.要产生一个线 ...

  7. 【java基础 13】两种方法判断hashmap中是否形成环形链表

    导读:额,我介绍的这两种方法,有点蠢啊,小打小闹的那种,后来我查了查资料,别人都起了好高大上的名字,不过,本篇博客,我还是用何下下的风格来写.两种方法,一种是丢手绢法,另外一种,是迷路法. 这两种方法 ...

  8. 实验04——java保留小数的两种方法、字符串转数值

    package cn.tedu.demo; import java.text.DecimalFormat; /** * @author 赵瑞鑫 E-mail:1922250303@qq.com * @ ...

  9. java动态代理的2种实现方式

    java的动态代理在接java的api上有说明,这里就不写了.我理解的代理: 对特定接口中特定方法的功能进行扩展,这就是代理.代理是通过代理实例关联的调用处理程序对象调用方法. 下面通过一个例子看一下 ...

随机推荐

  1. android模拟器使用gps定位

    在模拟器上获取GPS信息时,使用Location loc = LocationManager.getLastKnownLocation("gps");来获取location信息,但 ...

  2. JDBC二查询(web基础学习笔记八)

    一.建立数据库 --创建news表空间 CREATE TABLESPACE tbs_news DATAFILE 'F:\ORACLE\news.dbf' SIZE 10M AUTOEXTEND ON; ...

  3. 玩转oracle学习第五天

     1.上节回想 2.维护数据的完整性 3.管理索引 4.管理权限和角色 1.掌握维护oracle数据完整性的技巧  2.理解索引的概念,会建立索引  3.管理oracle的权限和角色   介绍:维 ...

  4. 用JavaScript 来创建 mac os x 程序这样是否好

    在网上看到的文章: 用 JavaScript 编写 OS X 应用 (Tyler Gaw)   这个文章的内容是不错的. 可是思路呢? 我们假设想学一种方法或工具,这样做好吗? 我看了上面的代码.假设 ...

  5. ios8.1.3Cydia重装

    1.下载deb包 2.把包放到/var/mobile/Media/下 3.终端输入:dpkg -i /var/mobile/Media/*.deb 然后输入:su -c uicache mobile ...

  6. 重要:VC DLL编程

    VC DLL编程 静态链接:每个应用程序使用函数库,必须拥有一份库的备份.多个应用程序运行时,内存中就有多份函数库代码的备份. 动态连接库:多个应用程序可以共享一份函数库的备份. DLL的调用方式:即 ...

  7. Androidmanifest.xml在Android项目中的作用

    以下是一个项目中的AndroidManifest.xml文件: <?xml version="1.0" encoding="utf-8"?> < ...

  8. 【mysql】Innodb三大特性之adaptive hash index

    1.Adaptive Hash Indexes 定义 If a table fits almost entirely in main memory, the fastest way to perfor ...

  9. VC6.0 +WDK 开发驱动的环境配置

    前段时间,系统偶感风寒,挂掉了,苦于又没有备份过,只有重装了.原来开发驱动的环境是VC6+DDK+DriverStudio3.2,当时配置的时候就花了好一阵功夫,也没有彻底搞清楚.现在要重装了,决定改 ...

  10. Mybatis中的@SelectKey注解

    一.创建Maven项目 在pom.xml中,添加mybatis依赖,mysql-jdbc依赖,把编译版本改为1.8 你问,为啥mybatis不会自动依赖mysql-jdbc,需要手动写明?答:因为my ...