AOP基础知识
AOP基础知识,详情见: https://blog.csdn.net/sinat_32502451/article/details/142291052
AOP 源码,详情见: https://blog.csdn.net/sinat_32502451/article/details/142291110
AopProxy
AopProxy 接口是配置的AOP代理的委托接口,允许创建实际的代理对象。
开箱即用的实现可用于 JDK 动态代理和 CGLIB 代理 。
public interface AopProxy {
/**
* 创建新的代理对象。使用AopProxy的默认类加载器(如果需要创建代理):通常是线程上下文类加载器。
*/
Object getProxy();
/**
* 创建新的代理对象。使用给定的类加载器(如果需要创建代理)。
*/
Object getProxy(@Nullable ClassLoader classLoader);
}
CglibAopProxy
代码: org.springframework.aop.framework.CglibAopProxy
CglibAopProxy 是 Spring AOP框架的基于CGLIB的AopProxy实现。
CglibAopProxy 实现了 AopProxy。
此类对象应通过代理工厂获得,由AdvisedSupport对象配置。这个类是Spring的AOP框架的内部,不需要由客户端代码直接使用。
DefaultAopProxyFactory将在必要时自动创建基于CGLIB的代理,例如在代理目标类的情况下。
Enhancer
源码:net.sf.cglib.proxy.Enhancer
Enhancer 是标准Jdk动态代理的替代品,用于生成动态子类以启用方法拦截,还允许代理扩展具体的基类。
Aop Cglib动态代理,会运用到 Enhancer、Callback、CglibAopProxy、MethodInterceptor、MethodProxy 等等。
Callback 接口
源码: org.springframework.cglib.proxy.Callback
被 net.sf.cglib.proxy.Enhancer 类调用的回调接口都会继承 Callback 接口。
public interface Callback {
}
MethodInterceptor
源码:org.springframework.cglib.proxy.MethodInterceptor
MethodInterceptor 继承了 Callback接口。参数包含 对象,方法,上面说过的 MethodProxy 等。
AOP中经常用来实现拦截方法的调用。
public interface MethodInterceptor extends Callback {
Object intercept(Object var1, Method var2, Object[] var3, MethodProxy var4) throws Throwable;
}
Cglib动态代理示例:
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
public class CglibProxyDemo {
public static class Target {
public void printHello() {
System.out.println("Hello World");
}
}
public static void main(String[] param) {
//Enhancer 是标准Jdk动态代理的替代品,用于生成动态子类以启用方法拦截,还允许代理扩展具体的基类。
Target proxy = (Target) Enhancer.create(Target.class, (MethodInterceptor) (p, method, args, methodProxy) -> {
System.out.println("before method.");
//以下 p的值是 com.example.demo.sourceCode.cglib.CglibDemo$Target$$EnhancerByCGLIB$$87c3a731@27c60c
// methodProxy的 fastClassInfo 有 f1为 class com.example.demo.sourceCode.cglib.CglibDemo$Target,
// f2为class com.example.demo.sourceCode.cglib.CglibDemo$Target$$EnhancerByCGLIB$$87c3a731
Object result = methodProxy.invokeSuper(p, args);
System.out.println("after method.");
return result;
});
proxy.printHello();
}
}
MethodProxy的 invokeSuper
MethodProxy的作用:当调用被拦截的方法时,Enhancer 生成的类会将此对象传递给已注册的 MethodInterceptor(方法拦截器) 对象。
它既可以用来调用原始方法,也可以在同一类型的不同对象上调用相同的方法。
源码: org.springframework.cglib.proxy.MethodProxy#invokeSuper
/**
* 调用指定对象上的原始方法。
*/
public Object invokeSuper(Object obj, Object[] args) throws Throwable {
try {
//实例化成员变量 fastClassInfo,包含了类及方法名称等属性。
init();
FastClassInfo fci = fastClassInfo;
//调用方法
return fci.f2.invoke(fci.i2, obj, args);
}
catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
/*
* 实例化 fastClassInfo.
*/
private void init() {
if (fastClassInfo == null) {
synchronized (initLock) {
if (fastClassInfo == null) {
CreateInfo ci = createInfo;
FastClassInfo fci = new FastClassInfo();
fci.f1 = helper(ci, ci.c1);
fci.f2 = helper(ci, ci.c2);
fci.i1 = fci.f1.getIndex(sig1);
fci.i2 = fci.f2.getIndex(sig2);
fastClassInfo = fci;
createInfo = null;
}
}
}
}
CglibAopProxy 生成代理对象
CglibAopProxy 生成代理对象的源码,比较核心。可以重点看看。
源码: org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader)
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating CGLIB 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;
//判断是否为 Cglib动态代理。
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
validateClassIfNecessary(proxySuperClass, classLoader);
// 创建 enhancer, 配置CGLIB增强器。
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
//获取 Callback数组。
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
//设置回调数组的Class类型
enhancer.setCallbackTypes(types);
// 生成代理类并创建代理实例。
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
//AOP异常
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
enhancer.setInterceptDuringConstruction(false);
//enhancer 设置回调数组 callbacks
enhancer.setCallbacks(callbacks);
//创建代理对象
return (this.constructorArgs != null && this.constructorArgTypes != null ?
enhancer.create(this.constructorArgTypes, this.constructorArgs) :
enhancer.create());
}
CglibAopProxy.DynamicAdvisedInterceptor
DynamicAdvisedInterceptor 是 CglibAopProxy的内部类。
通用AOP回调。当目标是动态的或代理未冻结时使用。
在 AOP 进行前置/后置通知,需要在目标方法在前后处理逻辑时,就会调用 CglibAopProxy.DynamicAdvisedInterceptor 的 intercept 方法。
源码: org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor#intercept
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
private final AdvisedSupport advised;
public DynamicAdvisedInterceptor(AdvisedSupport advised) {
this.advised = advised;
}
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 获取目标对象
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// 核心方法,重点看看。 创建一个方法调用
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
// 返回值
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
}
}
CglibMethodInvocation
CglibMethodInvocation 是 CglibAopProxy 的内部类。
CglibMethodInvocation 是 使用AOP代理的AOP方法调用的实现。
在需要调用 代理对象,进行方法调用时,就会使用 CglibMethodInvocation。
源码: org.springframework.aop.framework.CglibAopProxy.CglibMethodInvocation#CglibMethodInvocation
private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
private final MethodProxy methodProxy;
private final boolean publicMethod;
public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method,
Object[] arguments, @Nullable Class<?> targetClass,
List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
this.methodProxy = methodProxy;
this.publicMethod = Modifier.isPublic(method.getModifiers());
}
@Override
protected Object invokeJoinpoint() throws Throwable {
if (this.publicMethod) {
return this.methodProxy.invoke(this.target, this.arguments);
}
else {
return super.invokeJoinpoint();
}
}
}
ProxyMethodInvocation
代码:org.springframework.aop.ProxyMethodInvocation
允许访问方法调用所使用的代理。
public interface ProxyMethodInvocation extends MethodInvocation {
/**
* 返回此方法调用所通过的代理。
*/
Object getProxy();
/**
* 创建此对象的克隆。
*/
MethodInvocation invocableClone();
/**
* 创建此对象的克隆。
*/
MethodInvocation invocableClone(Object... arguments);
/**
* 设置此链中任何 Advice 中后续调用时使用的参数。
*/
void setArguments(Object... arguments);
/**
* 将具有给定值的指定用户属性添加到此调用中。
*/
void setUserAttribute(String key, @Nullable Object value);
/**
* 返回指定用户属性的值。
*/
@Nullable
Object getUserAttribute(String key);
}
标签:enhancer,14,--,Object,代理,CglibAopProxy,源码,proxy,advised
From: https://www.cnblogs.com/expiator/p/18446434