Spring 实现AOP的几个核心工作流程如下
1、核心工具类的创建
开启@EnableAspectJAutoProxy 注解的时候,实际上是把AOP核心工具类AnnotationAwareAspectJAutoProxyCreator添加到IOC容器的过程,这个类负责切面通知类的解析,并且负责代理对象的创建逻辑。
2、加载切面和通知
加载Aspect 的切面类,解析切面类(Aspect)对应的通知方法(advice) 和 切面规则(PointCut)。
3、创建代理Bean
IOC创建Bean(target)的时候和所有切面对象的PointCut匹配,PointCut命中的话则需要创建代理对象(Proxy),并且通过getBean()返回的是代理对象(Proxy)。
4、执行代理对象的方法。
根据代用的方法(Method)找到所有匹配的通知方法(Advice),这里会把符合调用的通知方法(advice)按照顺序(前置、后置、环绕、返回、异常)组成一个调用链(List),然后通过proced()方法依次执行调用链里面的方法。
1、创建AnnotationAwareAspectJAutoProxyCreator对象
使用AOP的时候我们都会通过一个注解(@EnableAspectJAutoProxy),或者在配置文件增加配置来开启AOP功能,而这个配置其实就是是否需要注册一个名叫AnnotationAwareAspectJAutoProxyCreator到IOC容器中去,如果没有开启这个配置的话,那么IOC容器就不会创建这个对象,那么也就无法扫描到我们的Aspect相关的切面类。
首先我们需要看AnnotationAwareAspectJAutoProxyCreator 类的关系结构图,这有助于我们后面理解AnnotationAwareAspectJAutoProxyCreator 的创建时机和执行时机。
(1)从@EnableAspectJAutoProxy注解源码我们可以看到,它引入了一个AspectJAutoProxyRegistrar的类。
decoration-color: initial;">@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
//省略代码
}
(2)然后AspectJAutoProxyRegistrar类实现了ImportBeanDefinitionRegistrar 接口。
熟悉IOC容器的话应该能理解实现了在ImportBeanDefinitionRegistrar .registerBeanDefinitions()方法中可以动态的往容器里面添加Bean的配置(BeanDefinition)信息,最终其实就是动态的往容器里面添加Bean。
ImportBeanDefinitionRegistrar .registerBeanDefinitions()源码
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//注册AnnotationAwareAspectJAutoProxyCreator到IOC容器,此Bean会在registerBeanPostProcessors时创建
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
//省略代码
}
(3)在ImportBeanDefinitionRegistrar .registerBeanDefinitions()方法里面会调用AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry) 方法注册一个bean id为“org.springframework.aop.config.internalAutoProxyCreator” 配置信息(BeanDefinition)到IOC容器。
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
最终调用AopConfigUtils.registerOrEscalateApcAsRequired方法()
private static BeanDefinition registerOrEscalateApcAsRequired(Class> cls, BeanDefinitionRegistry registry,
@Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
//定义顺序
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
(4)在IOC容器启动时候,会加载所有的BeanDefinition来实例化Bean, AnnotationAwareAspectJAutoProxyCreator 类实现了Ordered接口和 BeanPostProcessor接口,所以AnnotationAwareAspectJAutoProxyCreator 会优先于其他的Bean先创建,IOC容器会在容器刷新的时候就进行Bean的创建。
AbstractApplicationContext.refresh()
调用
AbstractApplicationContext.registerBeanPostProcessors()
最终调用
PostProcessorRegistrationDelegate.registerBeanPostProcessors()
因为实现了Ordered接口,所以会执行下面代码逻辑
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//...省略代码
// 然后注册实现了Ordered接口的BeanPostProcessors
List orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
//此处优先其它普通bean之前创建实现了Ordered接口的Bean对象
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//...省略代码
}
AnnotationAwareAspectJAutoProxyCreator整个配置加载和bean创建过程
2、切面和通知加载阶段
因为在创建代理的时候需要对所有我们定义的Aspect 切面类进行匹配,匹配的Aspect 我们才会创建代理,否则的话就代表对象不需要进行代理。而进行匹配前我们势必需要把IOC容器所有的Aspect和对应的Advice都加载好解析并缓存好,那么我们在创建的代理的时候就直接拿过来进行匹配使用了。
主要逻辑:
(1)、创建代理时候会从缓存的数据里面取得所有与当前对象匹配的Advice.
(2)、当缓存里面不存在时候再扫描所有的IOC容器bean,如果为Aspect类型对象则解析保存到缓存中。
方法调用流程如下:
入口:AbstractAutoProxyCreator.postProcessBeforeInstantiation()方法
public Object postProcessBeforeInstantiation(Class> beanClass, String beanName) throws BeansException {
//省略代码......
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
//省略代码......
return null;
}
调用 AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(),查找符合条件的Advisor
protected Object[] getAdvicesAndAdvisorsForBean(Class> beanClass, String beanName, @Nullable TargetSource targetSource) {
List advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
调用AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(),拿到所有Advisor 然后和当前对象进行匹配
findEligibleAdvisors(Class> beanClass, String beanName) {
//获取到所有切面通知方法
List candidateAdvisors = findCandidateAdvisors();
//匹配到符合当前对象的通知方法
List eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
//对通知方法集合进行排序
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
调用AbstractAdvisorAutoProxyCreator.findCandidateAdvisors()
findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}
调用BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans(),扫描容器的bean ,如果是Advisor 类型的都进行解析添加到缓存
public List findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
String[] advisorNames = null;
synchronized (this) {
advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the auto-proxy creator apply to them!
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
}
if (advisorNames.length == 0) {
return new LinkedList<>();
}
List advisors = new LinkedList<>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping advisor '" + name +
"' with dependency on currently created bean: " + ex.getMessage());
}
// Ignore: indicates a reference back to the bean we're trying to advise.
// We want to find advisors other than the currently created bean itself.
continue;
}
}
throw ex;
}
}
}
}
return advisors;
}
3、代理创建阶段
当IOC容器创建每个对象(doCreateBean)的时候,会在原对象创建完(createBeanInstance)并且依赖注入完之后(populateBean)之后调用一个初始化对象的方法(initializeBean),initializeBean方法里面会执行所有实现了BeanPostProcessor 接口的postProcessAfterInitialization()方法;
而我们在上面已经创建了的AOP核心类他就实现了BeanPostProcessor接口,所以这里所有的Bean都会执行AbstractAutoProxyCreator.postProcessAfterInitialization()逻辑;在这个方法里开始为我们的原生对象生成对应的代理对象。
调用流程如下:
在AbstractAutowireCapableBeanFactory.doCreateBean()方法里调用initializeBean()进行对象的初始化。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
//省略代码...........
//==创建bean实例 new Object()
instanceWrapper = createBeanInstance(beanName, mbd, args);
//===依赖注入
populateBean(beanName, mbd, instanceWrapper);
//===对象生成后执行BeanPostProcessor、init、Aware 相关逻辑, 返回最终暴露出去的bean对象
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
//省略代码...........
应用所有后置处理器
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
//省略代码....
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//==执行bean初始化之前的业务逻辑 (此处会执行实现了PostProcessors接口的对象逻辑)
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
//省略代码....
return wrappedBean;
}
遍历所有BeanPostProcessor调用对应的postProcessBeforeInitialization方法
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
调用AbstractAutoProxyCreator.postProcessAfterInitialization()方法
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;
}
调用AbstractAutoProxyCreator.wrapIfNecessary()开始创建代理
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//对应bean是否已经生成了代理
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//无需增强
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//如果是aop的工具类则直接返回,比如 advice pointcut advisor
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
//获取所有的拦截通知
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;
}
调用AbstractAutoProxyCreator.createProxy()创建代理对象
protected Object createProxy(Class> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
BeanNameConstants.contansBeanName(beanName);
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
调用ProxyFactory.getProxy()来决定是使JDK、或者CGlib来创建代理
public Object getProxy(@Nullable ClassLoader classLoader) {
//使用JDK、或者CGlib创建代理
return createAopProxy().getProxy(classLoader);
}
4、代理执行阶段
这里以JDK生成的动态代理为例,当代理对象执行对应的方法后统一都会进入JdkDynamicAopProxy.invoke()方法
这里主要是获取到当前代理对象的所有匹配的Advice,然后把所有的Advice按照顺序放到List集合里组成一个调用链,然后调用链依次调用proceed()方法执行对应通知和对象方法逻辑。
调用流程如下:
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 {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// 如果是调用equals 方法则执行equals的逻辑
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// 如果是调用hashCode方法,则执行hashCode的逻辑
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// 如果当前方法是Spring织入的DecoratingProxy接口中的方法,则返回目标对象的Class类型
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// 通过反射调用invoke
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);
// ==获得代理对象的方法执行链
List