SpringAOP源码解析总结

问题一、何时生成代理bean??

在getBean()过程中,进行了bean的实例化、依赖注入、初始化后,通过bean后处理器进行生成代理类。

在getBean()过程中的AbstractAutowireCapableBeanFactory类的 createBean ->doCreateBean 方法完成bean的创建和依赖注入后,进入initializeBean方法进行初始化

在初始化bean后,在bean后处理器的applyBeanPostProcessorsAfterInitialization生成代理bean ,  AbstractAutoProxyCreator 实现了SmartInstantiationAwareBeanPostProcessor后处理器接口调用wrapIfNecessary 根据切点判断是否有匹配到bean的Advisor通知器(包含通知和切点Advices只是通知) ,如果匹配到进行创建代理类。

创建代理调用createProxy方法里通过

ProxyFactory proxyFactory = new ProxyFactory();

proxyFactory.addAdvisor(advisor);

proxyFactory.setTargetSource(targetSource);

return proxyFactory.getProxy(getProxyClassLoader());//生成代理


DefaultAopProxyFactory类来返回实际创建代理类,如果是有目标类有接口实现是通过JDK代理实现,否则是CGliB实现

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {//配置文件配置Optimize或者ProxyTargetClass或者没有配置代理接口
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {//如果目标类有接口
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}

JdkDynamicAopProxy类方法创建代理类,该类继承了InvocationHandler接口实现了invoke拦截方法

public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);//经典JDK代理
}

通过配置方法默认是采用ProxyFactory 生成代理bean,

proxyFactoryBean是提供用户自定义配置方式的生成方式。

------------------------------------------------------------------------------------------到此bean的代理类已经生成完毕--------------------------------------------------------------------------------------------------

二、代理类如何外出增强业务逻辑??切面如何织入业务中??

生成代理类后,接口是注入的代理类,在调用方法时,会被代理类的invoke方法拦截。


1、通过proxyFactoryBean生成代理bean.

1)、拦截器链的初始化:通过配置文件取得配置文件中的advisor通知器。2)、通过JDK生成代理对象3)、代理对象实现了InvocationHandler接口。3)、在调用目标方法时invoke方法被触发5)、通过方法匹配获得拦截器链list 6)、通过递归循环调用拦截链list ,如果没有拦截链可以调用了就调用通过反射目标方法本身  。这样把增强逻辑织入进业务了。

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)) {//如果目标没有实现equles方法则采用代理类自带的方法
// The target does not implement the equals(Object) method itself.
return equals(args[0]);//判断逻辑:如果比较类是非JDK代理类直接返回false,如果是JDK代理类,且是自身返回true,否则比较两个代理的advised是否相同。
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {//如果I目标没有实现hashCode方法,采用代理类的hashcode方法
// The target does not implement the hashCode() method itself.
return hashCode();//JdkDynamicAopProxy.class.hashCode() * 13 + this.advised.getTargetSource().hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else 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);//通过目标类和方法和在advice中获得拦截链


// 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.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
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.
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.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;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

  ReflectiveMethodInvocation类,递归回调循环拦截链,如果拦截链调用完毕执行目标方法,这样把切面方法增强到业务逻辑中

protected ReflectiveMethodInvocation(
Object proxy, Object target, Method method, Object[] arguments,
Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {


this.proxy = proxy;
this.target = target;
this.targetClass = targetClass;
this.method = BridgeMethodResolver.findBridgedMethod(method);
this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);
this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
}

public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.

//从-1开始看目前的拦截器链是否调用完毕。如果调用完毕,执行目标方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();//调用目标方法AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}

Object interceptorOrInterceptionAdvice =
    this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
    (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {//动态匹配连接点,如果匹配成功,
return dm.interceptor.invoke(this);//调用适配的advice拦截方法。
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();//递归调用拦截链
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);//如果是环绕类型的直接调用
}
}

-----------------------------------------------------------------------------------------

适配的 拦截类例如 

public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {


private final AfterReturningAdvice advice;

/**
* Create a new AfterReturningAdviceInterceptor for the given advice.
* @param advice the AfterReturningAdvice to wrap
*/
public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();//递归调用
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());//执行增强方法
return retVal;
}


}

Spring看第一遍源码云里雾里的有些晕,再看看基础,基础应用深了,在dug源码就看明白了。

总结:JDK代理,代理类实现了所有实现接口方法,包括继承的父类实现的接口。不是接口的方法不会进行代理拦截。

         hashcode、equales方法代理类不重写的话,用spring默认的方法且不进行拦截增强,如果重新会进行拦截增强。

AOP源码学习解析:学习参考博客:https://www.cnblogs.com/wade-luffy/p/5767092.html#_label1

http://www.codeweblog.com/spring-aop%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90-%E5%9B%9B-spring-aop%E7%9A%84jdk%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值