cglib 多重 代理示例-2
from: http://thinkinjava.cn/2018/10/%E4%BD%BF%E7%94%A8-Cglib-%E5%AE%9E%E7%8E%B0%E5%A4%9A%E9%87%8D%E4%BB%A3%E7%90%86/ , https://blog.csdn.net/ahilll/article/details/82943836
/*
简单实现 Cglib 多重代理
先说一下思路:事实上很简单,只需要再拦截器里放一个过滤器链即可,用户在过滤器里拦截多重调用。
这些拦截器,就像你加 @Around 注解的方法,只不过我们这里没有 Spring 那么方便而已。
*/
public class Test {
public static void main(String[] args) {
Object proxy = ProxyFactory.create().getProxy(new SayHello());
proxy.toString();
} static class SayHello {
@Override
public String toString() {
return "hello cglib !";
}
}
}
核心代理工厂:
public class ProxyFactory {
private ProxyFactory() {}
public static ProxyFactory create() {
return new ProxyFactory();
}
public Object getProxy(Object origin) {
final Enhancer en = new Enhancer();
en.setSuperclass(origin.getClass());
List<Chain.PointInterface> list = new ArrayList<>();
list.add(new PointInterface1());
list.add(new PointInterface2());
System.out.println("---12->进入了 获取代理对象的方法: getProxy(Object origin)");
en.setCallback(new SpringCglibProxyInterceptor(new Chain(list, origin)));
return en.create();
}
private class SpringCglibProxyInterceptor implements MethodInterceptor {//在这个拦截器里放一个过滤器链 SpringCglibProxy
Chain chain;
public SpringCglibProxyInterceptor(Chain chain) {
System.out.println("---13->进入了 SpringCglibProxyInterceptor的构造方法");
this.chain = chain;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy)
throws Throwable {
System.out.println("---14->进入了 SpringCglibProxyInterceptor.class中 基层CglibPoxy接口的实现方法");
return chain.proceed2(); //引入 滤器链
}
}
}
public class Chain {
private List<PointInterface> list;
private int index = -1;
private Object target;
public Chain(List<PointInterface> list, Object target) {
System.out.println("---12.1->进入了 SpringCglibProxyInterceptor构造方法中的对象参数Chain的构造方法");
this.list = list;
this.target = target;
}
//滤器链
public Object proceed2() throws InterruptedException {
System.out.println("---15->进入了 基层CglibPoxy接口的实现方法 调用的proceed2()方法");
Object result;
if (++index == list.size()) { // 这是干正事
result = (target.toString());
System.err.println("---50->干正事-ing-(proceed2()方法中)Target Method invoke result : " + result);
System.err.println("---51->总结:1.切面一次性处理<正事>之前的琐事-->2.干正事-->3.切面一次性处理<正事>之后的琐事 ");
} else { // 这是干正事之前 做的事情
System.err.println("---49->干正事-before-(proceed2()方法中)做的事情--X: "+(index) + "--start");
PointInterface pointInterface = list.get(index);
result = pointInterface.proceed3(this);
System.err.println("---49->干正事-before-(proceed2()方法中)做的事情--X: "+(index) + "--end");
}
return result;
}
interface PointInterface {
Object proceed3(Chain chain) throws InterruptedException;
}
}
public class PointInterface1 implements Chain.PointInterface {
@Override
public Object proceed3(Chain chain) throws InterruptedException {
System.out.println("point 1 before");
Thread.sleep(20);
Object result = chain.proceed2();
Thread.sleep(20);
System.out.println("point 1 after");
return result;
}
}
public class PointInterface2 implements Chain.PointInterface {
@Override
public Object proceed3(Chain chain) throws InterruptedException {
System.out.println("point 2 before");
Thread.sleep(20);
Object result = chain.proceed2();
Thread.sleep(20);
System.out.println("point 2 after");
return result;
}
}
结果:
---12->进入了 获取代理对象的方法: getProxy(Object origin)
---12.1->进入了 SpringCglibProxyInterceptor构造方法中的对象参数Chain的构造方法
---13->进入了 SpringCglibProxyInterceptor的构造方法
---14->进入了 SpringCglibProxyInterceptor.class中 基层CglibPoxy接口的实现方法
---15->进入了 基层CglibPoxy接口的实现方法 调用的proceed2()方法
point 1 before
---49->干正事-before-(proceed2()方法中)做的事情--X: 0--start
---15->进入了 基层CglibPoxy接口的实现方法 调用的proceed2()方法
point 2 before
---49->干正事-before-(proceed2()方法中)做的事情--X: 1--start
---50->干正事-ing-(proceed2()方法中)Target Method invoke result : hello cglib !
---51->总结:1.切面一次性处理<正事>之前的琐事-->2.干正事-->3.切面一次性处理<正事>之后的琐事
---15->进入了 基层CglibPoxy接口的实现方法 调用的proceed2()方法
point 2 after
---49->干正事-before-(proceed2()方法中)做的事情--X: 2--end
point 1 after
---49->干正事-before-(proceed2()方法中)做的事情--X: 2--end
cglib 多重 代理示例-2的更多相关文章
- cglib 简单 代理示例-1
引用包cglib-xxx.jar非Maven项目还需要手动引用包asm-xxx.jar业务类(不需要定义接口)cglib代理类(实现接口MethodInterceptor) 异常信息(项目只引用了cg ...
- 使用 Cglib 实现多重代理
前言 由于 Cglib 本身的设计,无法实现在 Proxy 外面再包装一层 Proxy(JDK Proxy 可以),通常会报如下错误: Caused by: java.lang.ClassFormat ...
- cglib代理与jdk动态代理示例
先看基于jdk实现的动态代理实现例子 1.先声明一个接口类 public interface UserService{ public String getName(String msg); } 2.实 ...
- 【Java EE 学习 51】【Spring学习第三天】【cglib动态代理】【AOP和动态代理】【切入点表达式】
一.cglib动态代理 1.简介 (1)CGlib是一个强大的,高性能,高质量的Code生成类库.它可以在运行期扩展Java类与实现Java接口. (2) 用CGlib生成代理类是目标类的子类. (3 ...
- cglib源码分析(四):cglib 动态代理原理分析
本文分下面三个部分来分析cglib动态代理的原理. cglib 动态代理示例 代理类分析 Fastclass 机制分析 一.cglib 动态代理示例 public class Target{ publ ...
- Spring源码剖析5:JDK和cglib动态代理原理详解
AOP的基础是Java动态代理,了解和使用两种动态代理能让我们更好地理解 AOP,在讲解AOP之前,让我们先来看看Java动态代理的使用方式以及底层实现原理. 转自https://www.jiansh ...
- cglib动态代理代码示例
cglib动态代理代码示例 引用包cglib-xxx.jar 非Maven项目还需要手动引用包asm-xxx.jar 业务类(不需要定义接口) cglib代理类(实现接口MethodIntercept ...
- Spring学习总结(二)——静态代理、JDK与CGLIB动态代理、AOP+IoC
一.为什么需要代理模式 假设需实现一个计算的类Math.完成加.减.乘.除功能,如下所示: package com.zhangguo.Spring041.aop01; public class Mat ...
- 代理模式 & Java原生动态代理技术 & CGLib动态代理技术
第一部分.代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常 ...
随机推荐
- C# ref和out的本质
ref和out参数的效果一样,都是通过关键字找到定义在主函数里面的变量的内存地址,并通过方法体内的语法改变它的大小.不同点就是输出参数必须对参数进行初始化.输出参数和引用参数的区别:从CLR的角度来看 ...
- union和union all比较说明
执行sql语句:select '1' union select '3' union select '2' union select '1' 得到的结果集如下: 执行sql语句如下: select ' ...
- Android ListView常见配置说明
ListView是我们经常使用的控件,但是使用中却因为各种原因无法设置出我们需要的效果,现将常用的设置记录下来方便以后查询. 1.拖动时背景变黑 android:cacheColorHint=&quo ...
- spring boot: thymeleaf模板引擎使用
spring boot: thymeleaf模板引擎使用 在pom.xml加入thymeleaf模板依赖 <!-- 添加thymeleaf的依赖 --> <dependency> ...
- git查看本地分支关联(跟踪)的远程分支之间的对应关系,本地分支对应哪个远程分支
git branch -vv: [root@realserver git-test]# git branch -vv bug 23043a7 add new.txt master.* dev ...
- 44 CSS 浮动 模态框 定位
一.浮动 float : 浮动的盒子不占原来的位置,其下方的盒子会上移 父盒子会发生塌陷现象.同一级盒子right浮动,同级左边的盒子需要左浮动,right浮动的盒子才能上来 由于浮动框不在文档的普通 ...
- mac连接Windows远程桌面
先打开微软官方的下载面面:http://www.microsoft.com/zh-CN/download/details.aspx?id=18140 下载远程连接客户端 http://jingyan. ...
- 数据库,ADO.NET(ADO),Oledb(Odbc)和编程语言关系框架图
---恢复内容开始--- ---恢复内容结束---
- redhat linux 6.2 安装配置GUI
redhat6.2默认不安装GUI,启动时默认进入text模式,下面介绍下安装.配置GUI的步骤: 1.登录root 2.配置及测试yum vi /etc/yum.repos.d/rhel-sou ...
- JavaScript学习总结(十九)——使用js加载器动态加载外部Javascript文件
今天在网上找到了一个可以动态加载js文件的js加载器,具体代码如下: JsLoader.js 1 var MiniSite=new Object(); 2 /** 3 * 判断浏览器 4 */ 5 M ...