一、应用场景
AOP(切面编程)是 OOP的延续,可以通过预编译方式和运行期间动态代理实现不修改源码的情况下给程序代码统一增加功能的技术。即业务需求和系统需求分开解耦。例如:日志、事务、安全校验。
二、概念
-
切面:一个关注点的模块化,这个关注点可能横切多个对象,比如日志输出
-
连接点:程序执行过程中的行为
-
通知:切面对连接点所产生的动作,一个切面包括多个通知。
- 前置通知
- 后置通知
- 返回后通知
- 环绕通知
- 异常通知
-
切点:匹配连接点的断言,切面中所有的通知关注的连接点都是由切点表达。
-
目标对象:被切面所通知的对象。
-
AOP代理对象:JDK和CGLib
三、AOP源码
AOP是通过BeanPostProcessor 后置处理器开始的,bean的后置处理器是一个监听器,可以监听容器触发的Bean生命周期事件,后置处理器向容器注册以后,容器中管理的bean就具备接收IOC容器事件回调能力。
import org.springframework.beans.BeansException;
public interface BeanPostProcessor {
//bean初始化前提供回调入口
Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;
//bean初始化之后提供回调入口
Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
}
1、AbstractAutowireCapableBeanFactory 类对容器生成的bean添加后置处理器
BeanPostProcessor 后置处理器的调用发生在IOC容器完成bean实例对象创建和属性依赖注入完成之后,之前的源码分析中了解,当程序第一次调用getBean()方法向IOC容器获取指定bean时触发创建bean的实例对象然后属性依赖注入,真正的创建bean对象并进行依赖注入的是AbstractAutowireCapableBeanFactory 类的 doCreate()方法。源码如下:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null;
Class> beanType = instanceWrapper != null ? instanceWrapper.getWrappedClass() : null;
synchronized(mbd.postProcessingLock) {
if (!mbd.postProcessed) {
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
this.addSingletonFactory(beanName, new ObjectFactory
2、initializeBean()方法
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
//jdk安全机制验证权限
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction
BeanPostProcessors实现的子类很多,比如:AOP、数据校验等,下面以创建AOP代理对象的子类AbstractAutoProxyCreator类,该类重写了postProcessAfterInitialization()方法。
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
} else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
} else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
protected Object createProxy(Class> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory)this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (this.shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
this.evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
Advisor[] var7 = advisors;
int var8 = advisors.length;
for(int var9 = 0; var9 < var8; ++var9) {
Advisor advisor = var7[var9];
proxyFactory.addAdvisor(advisor);
}
proxyFactory.setTargetSource(targetSource);
this.customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (this.advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(this.getProxyClassLoader());
}
3、整个过程跟踪下来,发现最终调用的是 proxyFactory.getProxy(this.getProxyClassLoader());,这里就能猜测proxyFactory有JDK和CGLib两种,最终调用的是DefaultAopProxyFactory的createAopProxy()方法:
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
//JDK 代理实现
return new JdkDynamicAopProxy(config);
} else {
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.");
} else {
return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
}
}
}
继续跟踪,具体生成代码放在JdkDynamicAopProxy 类中,源码:
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);
this.findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
4、这个就是java 原生的jdk动态代理。那切面是如何织入的?
jdk动态代理,具体的逻辑是在InvocationHandler中,发现JdkDynamicAopProxy 就是InvocationHandler,直接看invoke()方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Class> targetClass = null;
Object target = null;
Object var13;
try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
Boolean var20 = this.equals(args[0]);
return var20;
}
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
Integer var18 = this.hashCode();
return var18;
}
if (method.getDeclaringClass() == DecoratingProxy.class) {
Class var17 = AopProxyUtils.ultimateTargetClass(this.advised);
return var17;
}
Object retVal;
if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) {
retVal = AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
return retVal;
}
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}
List
实现思路:
- 首先获取方法的通知链 InterceptChain,如果有通知则应用通知并执行连接点;
- 如果没有通知,直接反射执行连接点。这里最关键的是通知链 InterceptChain 的获取。
通知链是getInterceptorsAndDynamicInterceptionAdvice方法获取
5、getInterceptorsAndDynamicInterceptionAdvice方法
public List
实际的实现逻辑是由DefaultAdvisorChainFactory的getInterceptorsAndDynamicInterceptionAdvice方法来完成的,且获取的结果会被缓存,下面就是getInterceptorsAndDynamicInterceptionAdvice方法实现:
public ListgetInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Class> targetClass) { List interceptorList = new ArrayList(config.getAdvisors().length); Class> actualClass = targetClass != null ? targetClass : method.getDeclaringClass(); boolean hasIntroductions = hasMatchingIntroductions(config, actualClass); AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance(); Advisor[] var8 = config.getAdvisors(); int var9 = var8.length; for(int var10 = 0; var10 < var9; ++var10) { Advisor advisor = var8[var10]; MethodInterceptor[] interceptors; if (advisor instanceof PointcutAdvisor) { PointcutAdvisor pointcutAdvisor = (PointcutAdvisor)advisor; if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) { interceptors = registry.getInterceptors(advisor); MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher(); if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) { if (mm.isRuntime()) { MethodInterceptor[] var15 = interceptors; int var16 = interceptors.length; for(int var17 = 0; var17 < var16; ++var17) { MethodInterceptor interceptor = var15[var17]; interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm)); } } else { interceptorList.addAll(Arrays.asList(interceptors)); } } } } else if (advisor instanceof IntroductionAdvisor) { IntroductionAdvisor ia = (IntroductionAdvisor)advisor; if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) { interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); } } else { Interceptor[] interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); } } return interceptorList; }
这个方法执行后,advised中配置的连接点或者目标类全部转化为MethodIntercept,继续看下去拦截器链是怎么运行的
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
} else {
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
}
6、如果拦截器链为空,则直接反射调用目标方法,否则创建MethodIntercept,调用其proceed()方法,触发拦截器链执行。
具体的实现类ReflectiveMethodInvocation 中的 proceed() 方法如下:
public Object proceed() throws Throwable {
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return this.invokeJoinpoint();
} else {
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
return dm.methodMatcher.matches(this.method, this.targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
} else {
return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
}
}
}
protected Object invokeJoinpoint() throws Throwable {
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
通知拦截器链实际就是责任链模式 顺着拦截器链 递归调用。在往下就是AopUtils.invokeJoinpointUsingReflection
public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args) throws Throwable {
try {
ReflectionUtils.makeAccessible(method);
return method.invoke(target, args);
} catch (InvocationTargetException var4) {
throw var4.getTargetException();
} catch (IllegalArgumentException var5) {
throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" + method + "] on target [" + target + "]", var5);
} catch (IllegalAccessException var6) {
throw new AopInvocationException("Could not access method [" + method + "]", var6);
}
}
}
其实就是反射调用。



