动态代理,有两种情况,第一种是有接口的情况下,你可以选择为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. 自定义self.editButtonItem 改变自定义self.editButtonItem的背景图片

    一: // UIButton *editSome; 为全局变量,已开启ARC; editSome = [UIButton buttonWithType:UIButtonTypeCustom]; edi ...

  2. tomcat thread dump 分析

    前言 Java Thread Dump 是一个非常有用的应用诊断工具, 通过thread dump出来的信息, 可以定位到你需要了解的线程, 以及这个线程的调用栈. 如果配合linux的top命令, ...

  3. 如何分析Java虚拟机死锁

    Thread Dump and Concurrency Locks Thread dumps are very useful for diagnosing synchronization relate ...

  4. No value for key [org.hibernate.impl.SessionFactoryImpl 异常解决

    使用Hibernate+Spring进行CRUD操作时.出现例如以下类似异常信息: java.lang.IllegalStateException: No value for key [org.hib ...

  5. win7 登录后只能使用“临时配置文件”,原来的配置文件无法启用!

    这个问题,修改注册表就可以解决. 开始-> 运行-> 输入regedit,回车, 在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\Cur ...

  6. SVN如何查看修改的文件记录

    主要是有四个命令,svn log用来展示svn 的版本作者.日期.路径等等:svn diff,用来显示特定修改的行级详细信息:svn cat,取得在特定版本的某文件显示在当前屏幕:svn  list, ...

  7. windows2003密码忘记了该如何处理

    如果你有sql   server的管理员帐号,并且可以登录,尝试用下面的方法:         --用管理员连接sql,在查询分析器中执行:         --添加用户     exec   mas ...

  8. 6、javac命令详解

    javac [ options ] [ sourcefiles ] [ @files ] 参数可按任意次序排列. options 命令行选项. sourcefiles 一个或多个要编译的源文件(例如 ...

  9. PHP-线程安全与非线程安全版本的区别

    Windows版的PHP从版本5.2.1开始有Thread Safe(线程安全)和None Thread Safe(NTS,非线程安全)之分,这两者不同在于何处?到底应该用哪种?这里做一个简单的介绍. ...

  10. reindex-maven 私服(nexus)架设以及项目管理中遇到的问题及解决方案(updating)

    ---    用maven 的过程中 大问题小问题实在是不少 ,就不一篇文章一篇文章的写了,干脆写在一起 ---- -------  nexus 加索引 点击Administration菜单下面的Re ...