CGLIB代理类,用CGLIB来实现一个代理类。大致原理描述如下:

1、使用Enhancer类来生成一个继续于被代理类的子类,此子类会重写被代理类(父类)中所有的非final的public方法;

2、当调用代理类的某个方法时实际上通过一个MethodInterceptor委托来间接调用的;

3、MethodInterceptor的intercept方法会对被代理类的方法进行增强(增强的逻辑是通过Interceptor接口来实现的)并调用被代理类(super class)的相关方法。

调用过程如下图:

CglibProxy类实现核心代理逻辑,并提供一个Interceptor接口供客户端来实现增强逻辑。

package proxy;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; /**
* @author xfyou
*/
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class CglibProxy<T> { private final Class<T> targetClass;
private final MethodInterceptor methodInterceptor; public static <T> CglibProxy<T> newInstance(Class<T> targetClass, Interceptor interceptor) {
return new CglibProxy<>(targetClass, new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
interceptor.before(obj);
Object invokeResult;
try {
invokeResult = proxy.invokeSuper(obj, args);
} catch (Throwable e) {
interceptor.exception(obj, e);
throw new InvocationTargetException(e);
}
interceptor.after(obj);
return invokeResult;
}
});
} @SuppressWarnings("unchecked")
public T createNewObj() {
return (T) createNewEnhancer().create();
} private Enhancer createNewEnhancer() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(targetClass);
enhancer.setCallback(methodInterceptor);
return enhancer;
} public interface Interceptor { /**
* Do something before invoke the super class method
*
* @param obj Instances of proxied objects
*/
void before(Object obj); /**
* Do something after invoked the super class method
*
* @param obj Instances of proxied objects
*/
void after(Object obj); /**
* Do something when exception occurred when invoke the super class method
*
* @param obj Instances of proxied objects
* @param e Exception
*/
void exception(Object obj, Throwable e); } }

WorkProxy类用来对Work类进行代理,生成的是一个单例的代理类。

package proxy;

import proxy.CglibProxy.Interceptor;

/**
* @author xfyou
* @date 2019/10/15
*/
public class WorkProxy { private static Work proxyObject; private static Interceptor interceptor = new Interceptor() { @Override
public void before(Object obj) {
System.out.println("before");
} @Override
public void after(Object obj) {
System.out.println("after");
} @Override
public void exception(Object obj, Throwable e) {
System.out.println("exception");
} }; static {
proxyObject = CglibProxy.newInstance(Work.class, interceptor).createNewObj();
} public static Work get() {
return proxyObject;
} }

被代理的Work类如下:

package proxy;

/**
* Work
*/
public class Work { public void doWork() {
System.out.println("Do work");
} }

测试代码:

package proxy;

/**
* @author xfyou
* @date 2019/10/15
*/
public class Test { public static void main(String[] args) {
WorkProxy.get().doWork();
} }

最新文章

  1. vue-cli
  2. ASP.NET MVC中viewData、viewBag和templateData的区别
  3. EasyDarwin不能保存HLS列表的解决方案
  4. Cocoa pod的使用注意点
  5. linux卸载php
  6. grunt入门之grunt watch的使用
  7. [Computer Vision] SIFT特征学习笔记
  8. ipython with ubuntu
  9. 如何使用GOOLE
  10. Dubbo与Zookeeper、SpringMVC整合和使用
  11. module.exports与exports,export与export default之间的关系和区别
  12. building &#39;twisted.test.raiser&#39; extension error: Microsoft Visual C++ 14.0 is required. Get it with &quot;Microsoft Visual C++ Build Tools&quot;: http://landinghub.visualstudio.com/visual-cpp-build-tools
  13. Sql Server中的数据类型和Mysql中的数据类型的对应关系(转)
  14. HDU 1242 Rescue(BFS+优先队列)
  15. 【转】【CentOS】【Python】Centos7安装Python3的方法
  16. android无后缀二进制执行文件替代apk实现程序功能
  17. USB协议及认知
  18. QuantLib 金融计算——基本组件之 DateGeneration 类
  19. unity, 不要change Default sharedMaterial
  20. 一.Select 函数详细介绍【转】

热门文章

  1. Dalvik虚拟机结构——1
  2. 关于连接不上SVN的部分解决方案——No repository found in svn localhost
  3. PHP fsockopen 异步写入文件
  4. cad 画图面板的尺寸大小定义
  5. 【Mysql异常】[HY000][1030] Got error 28 from storage engine
  6. [TJOI2018]最长上升子序列
  7. 模板内部不支持原生js的方法?》》artTemplate模版方法注册window全部事件方法
  8. 音视频RTP数据包封装
  9. 数组的filter方法处理数组内对象元素时,会改变原值
  10. accept返回的socket的端口号和连接socket一样的!!! socket绑定信息结构