知识大全 CGLib实现变化字段探测的供能

Posted

篇首语:树高千尺有根,水流万里有源。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 CGLib实现变化字段探测的供能相关的知识,希望对你有一定的参考价值。

CGLib实现变化字段探测的供能  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  为了巩固 CGLib 的知识 下面我们实现一个稍微复杂一点的例子

  例 请实现一个拦截器 使其能够检测一个 JavaBean 的哪些字段改变了

  ( )首先定义一个 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;

  

  

  ( )定义一个 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 集合中

  ( )定义剖析用工具

  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 = 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() 通过这个方法我们可以得到所有的拦截器

  ( ) 主程序

  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( 地址 );

  info setAge( );

  info setName( tom );

    

  // 得到拦截器

  JavaBeanDataChangeInterceptor interceptor = JavaBeanInterceptorUtils

   getInterceptor(info);

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

  interceptor reset();

    

  // 对 JavaBean 做一些修改

  editPersonInf(info);

    

  // 得到修改了的字段

  Iterator it = interceptor getChangedPropSet(erator();

  while (it hasNext())

  

  System out println(it next());

  

  

    

  private static void editPersonInf(PersonInfo info)

  

  info setName( Jim );

  info setAddress( N Y Street );

  

     

  运行结果

  Address

  Name

    

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

    

cha138/Article/program/Java/hx/201311/26735

相关参考