cglib实现原理_CGLib实现变化字段探测的供能

JAVA认证交流指导 2021-07-10 网络整理 可可

【shitiku.jxxyjl.com--JAVA认证交流指导】

    为了巩固 cglib 的知识,下面我们实现一个稍微复杂一点的例子。例、请实现一个拦截器,使其能够检测一个 javabean 的哪些字段改变了。

( 1 )首先定义一个 javabean 。

public class personinfo

{

     private string name;

 

     private string email;

 

     private int age;

 

     private string address;

 

     public string getemail()

     {

         return email;

     }

 

     public void setemail(string email)

     {

         this.email = email;

     }

 

     public string getname()

     {

         return name;

     }

 

     public void setname(string name)

     {

         this.name = name;

     }

 

     public string getaddress()

     {

         return address;

     }

 

     public void setaddress(string address)

     {

         this.address = address;

     }

 

     public int getage()

     {

         return age;

     }

 

     public void setage(int age)

     {

         this.age = age;

     }

}

( 2 )定义一个 methodinterceptor ,这一步是最关键的 。

import java.lang.reflect.method;

import java.util.collections;

import java.util.hashset;

import java.util.set;

 

import net.sf.cglib.proxy.methodinterceptor;

import net.sf.cglib.proxy.methodproxy;

 

public class javabeandatachangeinterceptor implements methodinterceptor

{

     private static final string set = "set";

 

     private set changedpropset;

 

     public javabeandatachangeinterceptor()

     {

         changedpropset = new hashset();

     }

 

     public object intercept(object obj, method method, object[] args,

              methodproxy proxy) throws throwable

     {

         string name = method.getname();

         if (name.startswith(set))

         {

              string s = name.substring(set.length());

              changedpropset.add(s);

         }

         return proxy.invokesuper(obj, args);

     }

 

     public set getchangedpropset()

     {

         return collections.unmodifiableset(changedpropset);

     }

 

     public void reset()

     {

         changedpropset.clear();

     }

}

定义一个集合 changedpropset 用来存放修改了的字段名,增加了一个方法 reset 用来清空此集合,增加了一个 getchangedpropset 方法用来供外界得到修改了的字段,为了防止调用者对 changedpropset 做修改,因此我们采用 collections.unmodifiableset 对返回的集合进行不可修改的修饰。

在 intercept 方法中,我们判断如果被调用的方法以 set 开头,则把此字段名放入 changedpropset 集合中。

( 3 )定义剖析用工具类。

import net.sf.cglib.proxy.callback;

import net.sf.cglib.proxy.factory;

 

public class javabeaninterceptorutils

{

     public static javabeandatachangeinterceptor getinterceptor(

              object obj)

     {

         if (!(obj instanceof factory))

         {

              return null;

         }

         factory f = (factory) obj;

         callback[] callbacks = f.getcallbacks();

         for (int i = 0, n = callbacks.length; i < n; i++)

         {

              callback callback = callbacks[i];

              if (callback instanceof javabeandatachangeinterceptor)

              {

                   return (javabeandatachangeinterceptor) callback;

              }

         }

         return null;

     }

}

  这个 javabeaninterceptorutils 只有一个方法 getinterceptor ,这个方法用于从一个被 cglib 代理的 javabean 中取出拦截器 javabeandatachangeinterceptor 。

  前边提到了, cglib 实现拦截的方式就是生成被拦截类的子类,这个子类实现了 net.sf.cglib.proxy.factory 接口,这个接口中有一个非常重要的方法 getcallbacks() ,通过这个方法我们可以得到所有的拦截器 。

( 4 ) 主程序

public class mainapp

{

     public static void main(string[] args)

     {

         enhancer enhancer = new enhancer();

         enhancer.setsuperclass(personinfo.class);

         enhancer.setcallback(new javabeandatachangeinterceptor());

 

         personinfo info = (personinfo) enhancer.create();

         // 对生成的 javabean 做一些初始化

         info.setaddress(" 地址 1");

         info.setage(21);

         info.setname("tom");

 

         // 得到拦截器

         javabeandatachangeinterceptor interceptor = javabeaninterceptorutils

                   .getinterceptor(info);

         // 复位修改字段记录集合

         interceptor.reset();

 

         // 对 javabean 做一些修改

         editpersoninf(info);

 

         // 得到修改了的字段

         iterator it = interceptor.getchangedpropset().iterator();

         while (it.hasnext())

         {

              system.out.println(it.next());

         }

     }

 

     private static void editpersoninf(personinfo info)

     {

         info.setname("jim");

         info.setaddress("n.y street");

     }

}   

运行结果:

address

name

 

  这个“变化字段拦截器”是有一定实际意义的,比如可以用来实现“只保存修改了的字段以提高效率”等功能 。

 

  很多资料中都说如果要使用 jdk proxy ,被代理的对象的类必须要实现接口,这种说法是不严谨的。从上边的例子我们可以看出,正确的说法应该是:如果要使用 jdk proxy ,那么我们要通过代理调用的方法必须定义在一个接口中。“面向接口编程而不是面向实现编程”是 oop 开发中的一条基本原则,因此这种限制并不会对我们的开发造成障碍。

本文来源:https://shitiku.jxxyjl.com/javarenzhengjiaoliuzhidao/6239.html

  • 【我的安全经验谈】经验谈:我学习使用java的一点体会

    2002年初,因为公司的业务需要而学习java,并应用java开发项目。由于项目时间紧,没有充裕的时间系统学习java,对java的学习只能是项目需要用什么,就学什么,这种学习方法的上手快,但不扎实,在以后的工作中,因为java学的不扎实,吃了不少苦头。现在我学习应用java已经有一...

    发布于:2021-07-10

    详细阅读
  • 【j2ee学习路线】J2EE建议的学习路线

    网络上、书店都提供了很多资料,很多方式都可以得到j2ee方面的资料。如何系统的、高效的学习j2ee这个问题摆在我们面前。比如, 有些人在看完一大堆书后,动起手来时还是不知道怎么开始。等等这些问题是我们最难处理的。如何寻找到一条很好的方式方法呢?   其实, 换一个角度来看,比如,学英...

    发布于:2021-07-10

    详细阅读
  • 【eclipse osgi环境搭建】基于OSGi搭建动态化的系统

    搭建动态化的系统是作为java开发人员一直就非常追求的目标,一个系统能够动态化就意味着:★ 添加新功能时不需要重启系统;★ 修改已存在的功能时不需要重启系统;★ 删除一些不需要的功能时不需要重启系统;★ 修改系统中的配置时可以不需要重启系统即刻生效;★ 系统的业务行为可动态的改变。...

    发布于:2021-07-10

    详细阅读
  • java语言初学者书籍_对于初学者学习Java语言的建议

    初学者的任务是掌握java的语言规则和养成良好的编程习惯,其次才谈到对类库使用的熟练程度,再其次是oo思想的掌握与应用,再其次就是design pattern的问题了。   在这里我只想介绍几个对成功完成第一个阶段很有用的资料。   以下按照循序渐进的顺序进行:   1 the ja...

    发布于:2021-07-09

    详细阅读
  • 在java中_java中LinkedList集合类实现栈和队列

    栈和队列是两种特殊的线性表,它们的逻辑结构和线性表相同,只是其运算规则较线性表有更多的限制,故又称它们为运算受限的线性表。 linkedlist数据结构是一种双向的链式结构,每一个对象除了数据本身外,还有两个引用,分别指向前一个元素和后一个元素,和数组的顺序存储结构(如:arr...

    发布于:2021-07-09

    详细阅读
  • [苹果授权店sun]Sun授权ASEC-Java培训中心名录

    北京   中软总公司计算机培训中心   010-62179898     清华大学java培训中心   010-62773618     北京大学java培训中心   010-62755660     神州数码(中国)有限公司(北京)   010-68428888     北京新东方...

    发布于:2021-07-09

    详细阅读
  • 学java的心得_技巧心得:java学习体悟

    java 出现在我们眼前,时间还很短,当他还只是一个半成品的时候,我们就被告知,java将成为软件发展的规范和希望 然后,java出现了,jdk的出现,我们发现其实java并不习惯,因为我们已经适应了window下的visual编程,对于jdk这种编程方法已经很不喜欢,即使visu...

    发布于:2021-07-09

    详细阅读
  • scjp怎么考|考SCJP的失败经历总结

    终于在上个星期六过了scjp,可惜只有69%!还是说说我准备考试的过程吧。  本人没有java的实际开发经验(但有三五年的c++和delphi开发经验,对oop比较熟悉),为了考这试,准备了一个月左右,但之前看了《thinking in java》和《java2核心技术卷1:基础知识》...

    发布于:2021-07-08

    详细阅读
  • java四本圣经_Java行业的圣经-四本最重要的个人藏书

    java行业的圣经 四本最重要的个人藏书,他们的书名都不含java     作者 thomas e davis   译者     摘要     thomas davis 推荐了四本书,它们可以让你在java开发中受益非浅。这些书扩展了java的基本语法和语义,使你能更全面地理解面...

    发布于:2021-07-08

    详细阅读
  • 【走向共和】走向J2EE,漫长的道路

    初次涉及java领域,感觉到java入门是好像没有c,c++入门快,工具也没有什么turbo c,visual c++好用(自己的破机器实在陪不起jbuilder,贪婪的家伙,以后一定要收拾她)。什么java_home,classpath,虚拟机等概念都是初次基础,旁边的人都很少用ja...

    发布于:2021-07-08

    详细阅读

Copyright @ 2011- 考试题库网 All Rights Reserved. 版权所有

免责声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。

 站长统计