AOP实现原理
1、切面(Aspect):面向规则,具有相同规则的方法的集合体。
2、通知(Advice):回调。
3、切入点(Pointcut):需要代理的具体方法。
4、目标对象(Target Object):被代理的对象。
5、AOP代理(AOP Proxy):主要有两种方式 JDK和CGLib。
6、前置通知(Before Advice):在invoke Pointcut之前调用、织入的方法。
7、后置通知(After Advice):Pointcut之后调用、织入的方法。
8、返回后通知(After Return Advice):返回值为非void的织入的方法。
9、环绕通知(Around Advice):只要触发调用,就织入的方法。
10、异常通知(After Throwing Advice):Pointcut抛出异常就织入的方法。
AOP的流程分三步:
- 创建代理类
- 代码织入(invoke)
- 回调通知
创建代理类
在AbstractAutowireCapableBeanFactory类中的doCreateBean()方法中,在populateBean()方法之后,有一个initializeBean()方法,初始化Bean对象用的:
//初始容器创建的Bean实例对象,为其添加BeanPostProcessor后置处理器
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
//JDK的安全机制验证权限
if (System.getSecurityManager() != null) {
//实现PrivilegedAction接口的匿名内部类
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//为Bean实例对象包装相关属性,如名称,类加载器,所属容器等信息
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
//对BeanPostProcessor后置处理器的postProcessBeforeInitialization
//回调方法的调用,为Bean实例初始化前做一些处理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
//调用Bean实例对象初始化的方法,这个初始化方法是在Spring Bean定义配置
//文件中通过init-method属性指定的
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, ""Invocation of init method failed"", ex);
}
//对BeanPostProcessor后置处理器的postProcessAfterInitialization
//回调方法的调用,为Bean实例初始化之后做一些处理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
直接看bean初始化后的回调处理方法:applyBeanPostProcessorsAfterInitialization();
在这个方法,进入postProcessAfterInitialization()方法。此处会有多个类可以选择,我们选择AbstractAutoProxyCreator类:
进入这个方法:
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
这个方法return了另一个方法wrapIfNecessary(),顾名思义,需要包装这个bean的时候才包装:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 判断是否不应该代理这个bean
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 获取这个bean的advice
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
前面一段是用来判断这个bean是否需要包装,后面的createProxy()就是创建代理了。首先通过getAdvicesAndAdvisorsForBean()方法,获取这个bean附带了哪些通知advice,获取这个bean的advice后,才能创建代理。
if (specificInterceptors != DO_NOT_PROXY)
DO_NOT_PROXY
定义为null,这句话表示如果这个bean没有任何的通知,则不创建代理。
进入getAdvicesAndAdvisorsForBean()方法:(AbstractAdvisorAutoProxyCreator类)
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
进入findEligibleAdvisors()方法:
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
来看一下对advice的排序动作:
protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
AnnotationAwareOrderComparator.sort(advisors);
return advisors;
}
通过比较器AnnotationAwareOrderComparator的排序规则来排序。
回到findEligibleAdvisors(Class<?> beanClass, String beanName)方法,通过这个方法的参数:Class<?> beanClass, String beanName,可以知道这个方法只能得到的是bean类有哪些advice,还不知道这个类具体是什么方法有advice。
现在我们获取到了这个bean的List\<Advisor>,回到AbstractAutowireCapableBeanFactory类的wrapIfNecessary()方法,看它的createProxy()方法:
这个方法主要通过proxyFactory.getProxy(getProxyClassLoader())
这句话来创建代理,进入ProxyFactory的getProxy()方法:
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
进入createAopProxy()方法:
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
再进入createAopProxy(this),来到了DefaultAopProxyFactory类:
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
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);
}
}
这个方法用以判断是用JDK方式还是用Cglib方式生成代理。
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
这一段表示,当这个类是一个接口,或者是一个代理类时,使用的是JDK的动态代理,否则使用Cglib动态代理。返回的是JdkDynamicAopProxy或者CglibAopProxy,这两个统一implements了AopProxy,所以createAopProxy()方法返回的就是AopProxy。
先来看一下JdkDynamicAopProxy的getProxy()方法:
public Object getProxy(@Nullable 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);
}
来看Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
,这个方法有三个参数:
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
这个方法有三个参数:
-
loader:用哪个类加载器去加载代理对象
-
interfaces:动态代理类需要实现的接口
-
h:动态代理方法在执行时,会调用h里面的invoke方法去执行
这个方法就是用于为指定类装载器、一组接口及调用处理器生成动态代理类实例的方法。通过这个方法,我们生成了一个代理类。
代码织入(invoke)
代理类生成之后,就需要对其方法进行织入。主要有两个组件:
- Intercepter:拦截器,责任链的组件,invoke();
- Invocation:调用器,调用通知回调的组件,proceed(),执行这个拦截器里的方法。
以JdkDynamicAopProxy为例,JdkDynamicAopProxy实现了InvocationHandler接口,重写了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;
Object target = null;
try {
//如果没有重写equals()方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
//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;
}
// Get as late as possible to minimize the time we ""own"" the target,
// in case it comes from a pool.
//获得目标对象的类
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// Get the interception chain for this method.
//获取可以应用到此方法上的Interceptor列表
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.
//如果没有可以应用到此方法的通知(Interceptor),此直接反射调用 method.invoke(target, args)
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...
//创建MethodInvocation
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);
}
}
}
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
这句话获取到了这个通知的拦截器链chain(责任链)。
进入这个getInterceptorsAndDynamicInterceptionAdvice()方法:
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
// 从缓存中获取
List<Object> cached = this.methodCache.get(cacheKey);
// 缓存未命中,则进行下一步处理
if (cached == null) {
// 获取所有的拦截器
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
// 存入缓存
this.methodCache.put(cacheKey, cached);
}
return cached;
先获取缓存中的,若有则将拦截器链的缓存返回;若没有则从advisorChainFactory获取所有拦截器。
若这个chain不为空,则执行:
retVal = invocation.proceed();
进入proceed()方法(ReflectiveMethodInvocation类):
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
//如果Interceptor执行完了,则执行joinPoint
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
//如果要动态匹配joinPoint
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);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
//动态匹配失败时,略过当前Intercetpor,调用下一个Interceptor
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
//执行当前Intercetpor
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
首先判断这次执行的下标(currentInterceptorIndex)是不是责任链的最后一个,若是则执行invokeJoinpoint(),若不是则往下执行(++currentInterceptorIndex)。
然后后判断是不是一个Interceptor,若不是,则继续下一个proceed();若是,则调用dm.interceptor.invoke(this)
(interceptor此时是封装在InterceptorAndDynamicMethodMatcher即dm中,所以调用dm的interceptor的invoke方法),这个invoke(this)每次会将this即ReflectiveMethodInvocation对象作为参数传入,以便在方法结束后回到proceed()方法。
进入invoke方法,会出现许多类,我们选择其中一个例如MethodBeforeAdviceInterceptor(before)的invoke方法:
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
return mi.proceed();
}
调用advice的before()方法,再调用proceed()。
换after的方法例如AfterReturningAdviceInterceptor的invoke()看一下:
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
此时,先进行proceed()之后再调用advice的after方法。
再来看看异常通知After Throwing Advice,例如ThrowsAdviceInterceptor的invoke():
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
catch (Throwable ex) {
Method handlerMethod = getExceptionHandler(ex);
if (handlerMethod != null) {
invokeHandlerMethod(mi, ex, handlerMethod);
}
throw ex;
}
}
此时代码会在catch里执行。
时序图: