JdkDynamicAopProxy与CglibAopProxy介绍
继续上一篇的介绍
1、上一篇分析到createAopProxy方法,创建Aop代理对象
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
2、进入DefaultAopProxyFactory类的createAopProxy方法

3、创建代理对象后,进入getProxy方法
this.singletonInstance = getProxy(createAopProxy());
protected Object getProxy(AopProxy aopProxy) {
return aopProxy.getProxy(this.proxyClassLoader);
}
分别进入对应的JdkDynamicAopProxy与CglibAopProxy的getProxy方法
JdkDynamicAopProxy类对应的getProxy方法如下图:

JdkDynamicAopProxy中的invoke方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Class targetClass = null;
Object target = null;
try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// May be null. Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}
// Get the interception chain for this method.
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
}
else {
// We need to create a method invocation...
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
}
// Massage return value if necessary.
if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
4、CglibAopProxy的getProxy方法
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating CGLIB2 proxy: target source is " + this.advised.getTargetSource());
}
try {
Class rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class[] additionalInterfaces = rootClass.getInterfaces();
for (Class additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass);
// Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setStrategy(new UndeclaredThrowableStrategy(UndeclaredThrowableException.class));
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setInterceptDuringConstruction(false);
Callback[] callbacks = getCallbacks(rootClass);
enhancer.setCallbacks(callbacks);
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
Class[] types = new Class[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
Object proxy;
if (this.constructorArgs != null) {
proxy = enhancer.create(this.constructorArgTypes, this.constructorArgs);
}
else {
proxy = enhancer.create();
}
return proxy;
}
catch (CodeGenerationException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
this.advised.getTargetClass() + "]: " +
"Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
this.advised.getTargetClass() + "]: " +
"Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Exception ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
JdkDynamicAopProxy与CglibAopProxy介绍的更多相关文章
- Spring AOP高级——源码实现(3)AopProxy代理对象之JDK动态代理的创建过程
spring-aop-4.3.7.RELEASE 在<Spring AOP高级——源码实现(1)动态代理技术>中介绍了两种动态代理技术,当然在Spring AOP中代理对象的生成也是运用 ...
- 转 分享我在阿里工作十年接触过Java框架设计模式
转 原文: 分享我在阿里工作十年接触过Java框架设计模式 一.前言 说起来设计模式,大家应该都耳熟能详,设计模式代表了软件设计的最佳实践,是经过不断总结提炼出来的代码设计经验的分类总结,这些模式或者 ...
- spring---aop(4)---Spring AOP的CGLIB动态代理
写在前面 前面介绍了Spring AOP的JDK动态代理的过程,这一篇文章就要介绍下Spring AOP的Cglib代理过程. CGLib全称为Code Generation Library,是一个强 ...
- Spring Aop技术原理分析
本篇文章从Aop xml元素的解析开始,分析了Aop在Spring中所使用到的技术.包括Aop各元素在容器中的表示方式.Aop自动代理的技术.代理对象的生成及Aop拦截链的调用等等.将这些技术串联起来 ...
- spring---aop(2)---Spring AOP的JDK动态代理
写在前面 spring 事务是springAOP 的一个实现.我们以分析spring的事务,来分析spring的AOP实现. 基本知识 如果目标方法被spring的事务声明,则执行该目标方法的对象就会 ...
- Spring里的aop实现方式和源码分析
使用"横切"技术,AOP把软件系统分为两个部分:核心关注点和横切关注点.业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点.横切关注点的一个特点是,他们经常发生在核心关 ...
- spring源码解析之AOP原理
一.准备工作 在这里我先简单记录下如何实现一个aop: AOP:[动态代理] 指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式: 1.导入aop模块:Spring AOP:(s ...
- spring源码系列8:AOP源码解析之代理的创建
回顾 首先回顾: JDK动态代理与CGLIB动态代理 Spring中的InstantiationAwareBeanPostProcessor和BeanPostProcessor的区别 我们得知 JDK ...
- Spring AOP 源码分析
一.准备工作 在这里我先简单记录下如何实现一个aop: AOP:[动态代理] 指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式: 1.导入aop模块:Spring AOP: ...
随机推荐
- base64的使用
import base64with open("test.jpg", "rb") as f: file = f.read()file_base64 = base ...
- dom4j 解析字符串成树形结构
引入maven依赖: <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artif ...
- PHP java时间戳转php时间戳
/** * java时间戳转php时间戳 * @param int $javaUt java的时间戳 * @return int * @Date 2019/8/26 */ public static ...
- CodeCombat第一关:KITHGARD地牢之KITHGARD精通
https://www.cnblogs.com/OctoptusLian/p/7397602.html https://www.jianshu.com/p/065581a84879 https://w ...
- Pure C static coding analysis tools
Cppcheck - A tool for static C/C++ code analysiscppcheck.sourceforge.netCppcheck is a static analysi ...
- python+正则+多进程爬取糗事百科图片
话不多说,直接上代码: # 需要的库 import requests import re import os from multiprocessing import Pool # 请求头 header ...
- Supermarket(贪心/并查集)
题目链接 原创的博客 题意: 超市里有N个商品. 第i个商品必须在保质期(第di天)之前卖掉, 若卖掉可让超市获得pi的利润. 每天只能卖一个商品. 现在你要让超市获得最大的利润. n , p[i], ...
- js插件---webuploader 使用(lavarel中使用)
js插件---webuploader 使用(lavarel中使用) 一.总结 一句话总结: 多去看几个具体使用的实例,很多blog教程都有坑,多看几个交叉印证可以没那么多坑 1.webuploader ...
- ImportError: cannot import name HTTPSHandler
原因在于openssl,openssl-devel两个文件包未正确安装.用下来的命令来安装: 2 yum install openssl -y yum install openssl-devel -y ...
- L1141
一,看题 1,位于0格可移动到相邻得1格.位于1格可移动到相邻的0格上. 2,从某一格开始可以移动的格子数.(应该不能重复,否则不久循环了.那就意味着我们可以要标记喽?) 3 二,写题 1,你是一次一 ...