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设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常 ...
随机推荐
- telnet 命令使用方法详解,telnet命令怎么用?
什么是Telnet? 对于Telnet的认识,不同的人持有不同的观点,可以把Telnet当成一种通信协议,但是对于入侵者而言,Telnet只是一种远程登录的工具.一旦入侵者与远程主机建立了Telnet ...
- JDK1.7 新特性
1:switch中可以使用字串 String s = "test"; switch (s) { case "test" : System. ...
- Lucky Array CodeForces - 121E (线段树,好题)
题目链接 题目大意: 定义只含数字$4,7$的数字为幸运数, 给定序列, 区间加正数, 区间询问多少个幸运数 题解: 对于每一个数, 求出它和第一个比它大的幸运数之差, 则问题转化为区间加,查询$0$ ...
- 牛客网暑期ACM多校训练营(第一场)I Substring
题意:给你一个只有abc的字符串,求不相同的子串,(不同构算不同,例如aba和bab算同构) 题解:很显然,如果不考虑同构的问题,我们直接上sa/sam即可,但是这里不行,我们考虑到只有abc三种字符 ...
- 解析XML文档大致流程以及相关方法
---恢复内容开始--- 使用dom解析XML文档的大致流程(要导入dom4j)1:创建SAXReader2:使用SAXReader读取xml文档,并生成对应的Document对象,该对象保存了该文档 ...
- UVA-818 Cutting Chains (位压缩+暴力搜索)
题目大意:一种环能打开和闭合.现在有n(1<=n<=15)个编号为1~n的环错综复杂的连接着,要打开一些环重新连接使这n个环能构成一条链,问最少需要打开几次环可达到目的? 题目分析:用二进 ...
- Leetcode 89
回溯写到自闭:不想就删了: class Solution { public: vector<int> grayCode(int n) { vector<vector<int&g ...
- html5-磊哥
<!doctype html><html lang="en"> <head> <meta charset=" ...
- K8S镜像删除及环境清理
环境清理: #删除所有容器sudo docker rm -f $(sudo docker ps -qa) #删除/var/etcd目录sudo rm -rf /var/etcd #删除/var/lib ...
- angular2使用ng g component navbar创建组件报错
Error: ELOOP: too many symbolic links encountered, stat 'C:\Users\inn\angulardemo\node_modules\@angu ...