@EnableAspectJAutoProxy

@EnableAspectJAutoProxy注解可以用来开启AOP,那么就从@EnableAspectJAutoProxy入手学习一下Spring AOP的实现原理。

  1. @EnableAspectJAutoProxy导入了AspectJAutoProxyRegistrar。
  2. 定义了proxyTargetClass属性,表示是否使用CGLIB生成代理对象,默认返回false,默认是使用JDK动态代理创建代理对象的。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)// 导入了AspectJAutoProxyRegistrar
public @interface EnableAspectJAutoProxy { /**
* 是否使用CGLIB生成代理对象,默认为false,默认是使用JDK动态代理创建代理对象的
*/
boolean proxyTargetClass() default false; /**
* 是否暴露代理
*/
boolean exposeProxy() default false; }

AspectJAutoProxyRegistrar

AspectJAutoProxyRegistrar是一个代理注册器,它实现了ImportBeanDefinitionRegistrar接口,ImportBeanDefinitionRegistrar可以向容器中注册bean,AspectJAutoProxyRegistrar实现了它应该是为了向容器中注册bean,那么看一下registerBeanDefinitions方法里面注册了什么

在registerBeanDefinitions方法中它调用了AopConfigUtils的registerAspectJAnnotationAutoProxyCreatorIfNecessary方法向容器中注册了自动代理创建器,通过名称可以看出它与AspectJ注解以及代理创建有关

/**
* AspectJ自动代理注册器
*/
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { /**
* 注册BeanDefinitions
*/
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 向容器中注册代理创建器
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
// 获取proxyTargetClass
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
// 获取exposeProxy
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}

注册自动代理创建器

registerAspectJAnnotationAutoProxyCreatorIfNecessary在AopConfigUtils中实现:

  1. 定义了一个自动代理创建器集合,是一个List,List里面的存储顺序代表了优先级,一共有三种代理创建器

    • InfrastructureAdvisorAutoProxyCreator:优先级最低
    • AspectJAwareAdvisorAutoProxyCreator:优先级较InfrastructureAdvisorAutoProxyCreator高
    • AnnotationAwareAspectJAutoProxyCreator:优先级最高
  2. Spring AOP默认使用的是AnnotationAwareAspectJAutoProxyCreator类型的创建器,向容器中注册的时候会判断容器中是否已经存在代理创建器:
    • 如果已经存在,从容器中取出创建器,判断优先级是否比AnnotationAwareAspectJAutoProxyCreator高,如果低于AnnotationAwareAspectJAutoProxyCreator,则使用AnnotationAwareAspectJAutoProxyCreator进行替换。
    • 如果不存在,直接向容器中注册AnnotationAwareAspectJAutoProxyCreator类型的bean即可。
public abstract class AopConfigUtils {

    /**
* 自动代理创建器beanName
*/
public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
"org.springframework.aop.config.internalAutoProxyCreator"; /**
* 自动创建器集合,是一个List,List里面的存储顺序代表了优先级
*/
private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<>(3); static {
// 向List中添加具体的代理创建器
APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
} @Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
// 调用下面的registerAspectJAnnotationAutoProxyCreatorIfNecessary方法
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
} @Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 这里可以看到,注册的是AnnotationAwareAspectJAutoProxyCreator类型的
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
} @Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
// 如果容器中已经包含名称为AUTO_PROXY_CREATOR_BEAN_NAME的bean
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
// 从容器中获取
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
// 如果当前要注册的bean与容器中已经存在的bean类型不一致
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
// 获取容器中存在的bean的优先级
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
// 获取要注册的bean的优先级
int requiredPriority = findPriorityForClass(cls);
// 容器中存在的bean的优先级比当前要注册的低
if (currentPriority < requiredPriority) {
// 使用当的class进行注册,也就是AnnotationAwareAspectJAutoProxyCreator
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
// 创建BeanDefinition
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;
}
}

AbstractAutoProxyCreator

自动代理创建器AbstractAutoProxyCreator用于创建代理对象,Spring AOP使用的是AnnotationAwareAspectJAutoProxyCreator类型的创建器,它是AbstractAutoProxyCreator的子类,继承关系如下:

AnnotationAwareAspectJAutoProxyCreator的主要方法都在AbstractAutoProxyCreator中实现,AbstractAutoProxyCreator实现了SmartInstantiationAwareBeanPostProcessor,它是Spring的Bean后置处理器,后置处理器有两个比较重要的方法:

postProcessBeforeInstantiation:在bean实例化之前执行的方法,如果有自定义的TargetSource则在这个时候就创建代理对象,可以先不管这里,主要看postProcessAfterInitialization方法。

postProcessAfterInitialization:在bean初始化之后执行的方法,这时候bean已经实例化完毕但是还没有设置属性等信息,调用了wrapIfNecessary方法判断是否有必要生成代理对象,如果不需要创建代理对象直接返回即可,反之需要调用getAdvicesAndAdvisorsForBean获取Advice和Advisor,然后创建代理对象。

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware { /**
* 在bean实例化之前执行的方法
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
} // 如果有自定义的TargetSource则创建代理对象
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
// 创建代理对象
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} return null;
} /**
* 在bean初始化之后执行的方法
*/
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
// 构建缓存Key
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 是否有必要创建代理
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
} /**
* 是否有必要生成代理对象
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 如果是基础类或者需要跳过则不创建代理对象,将bean加入到advisedBeans中即可
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
} // 获取bean的Advices和Advisors
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;
}
}

跳过代理对象创建的判断

跳过代理对象的创建主要通过以下两个方法判断的:

1.调用isInfrastructureClass判断是否是基础类,如果是则跳过代理创建。

2.调用shouldSkip方法判断是否需要跳过创建代理。

isInfrastructureClass

需要注意AOP使用的是AnnotationAwareAspectJAutoProxyCreator作为代理创建器,所以需要先看AnnotationAwareAspectJAutoProxyCreator是否重写了该方法,实际上它确实重写isInfrastructureClass方法,在里面它调用了父类的AbstractAutoProxyCreator的isInfrastructureClass和aspectJAdvisorFactory的isAspect进行判断:

  • isInfrastructureClass:如果是Advice、Pointcut、Advisor、AopInfrastructureBean及其子类则跳过创建,这些是Spring的基础类,不需要进行代理。
  • isAspect:是否有Aspect注解并且不是通过Ajc编译的类则是一个切面。

总结:如果是Advice、Pointcut、Advisor、AopInfrastructureBean及其子类或者bean是一个切面并且不是通过Ajc编译的则跳过代理创建,并将当前bean的缓存key加入到advisedBeans中(wrapIfNecessary中可以看到)。

public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {

    @Override
protected boolean isInfrastructureClass(Class<?> beanClass) {
// 调用AbstractAutoProxyCreator的isInfrastructureClass和aspectJAdvisorFactory的isAspect方法判断,在AbstractAspectJAdvisorFactory中有实现
return (super.isInfrastructureClass(beanClass) ||
(this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
}
} // AbstractAutoProxyCreator
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
/**
* 是否是基础类
*/
protected boolean isInfrastructureClass(Class<?> beanClass) {
// 如果是Advice、Pointcut、Advisor、AopInfrastructureBean类型
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && logger.isTraceEnabled()) {
logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
}
return retVal;
} } // AbstractAspectJAdvisorFactory
public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFactory {
/**
* 是否是切面
*/
@Override
public boolean isAspect(Class<?> clazz) {
// 是否有Aspect注解并且不是通过Ajc编译的类
return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
} // 判断是否有Aspect注解
private boolean hasAspectAnnotation(Class<?> clazz) {
// 是否有Aspect注解
return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
} /**
* 是否通过Ajc编译
*/
private boolean compiledByAjc(Class<?> clazz) {
for (Field field : clazz.getDeclaredFields()) {
if (field.getName().startsWith(AJC_MAGIC)) {
return true;
}
}
return false;
}
}

shouldSkip

AnnotationAwareAspectJAutoProxyCreator中重写的shouldSkip方法具体实现在父类AspectJAwareAdvisorAutoProxyCreator里面,它获取所有候选的Advisor进行遍历,判断Advisor是否是AspectJPointcutAdvisor类型并且当前的bean与advisor的AspectName切面名称一致则跳过代理创建:

public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
/**
* 是否跳过代理创建
*/
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// 获取候选的Advisors
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
// 如果是AspectJPointcutAdvisor类型并且当前的bean与advisor的AspectName切面名称一致,则跳过代理创建
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
// 调用父类的shouldSkip判断
return super.shouldSkip(beanClass, beanName);
}
}

获取所有的Advice和Advisor

getAdvicesAndAdvisorsForBean方法在AbstractAdvisorAutoProxyCreator中实现,它又调用了findEligibleAdvisors方法获取所有可应用到当前bean的Advisors:

  1. 调用findCandidateAdvisors获取所有候选的Advisor,需要注意的是虽然AbstractAdvisorAutoProxyCreator类中实现了findCandidateAdvisors,但是向容器中注册代理创建器实际的类型是AnnotationAwareAspectJAutoProxyCreator,它重写了findCandidateAdvisors方法,所以会先进入AnnotationAwareAspectJAutoProxyCreator的findCandidateAdvisors方法,它里面又调用了父类的findCandidateAdvisors,这时候才会进入AbstractAdvisorAutoProxyCreator的方法。
  2. 从所有候选的Advisor中过滤出可以适用于当前bean的Advisor,findAdvisorsThatCanApply具体实现逻辑在AopUtils中。
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
// 调用findEligibleAdvisors获取Advisor
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
} /**
* 获取Advisor
*/
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 1.获取所有的Advisor,需要注意实际的类型是AnnotationAwareAspectJAutoProxyCreator,所以会先进入它的findCandidateAdvisors方法中
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 2.获取可以应用到当前bean的Advisor
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
} /**
* AbstractAutoProxyCreator中获取所有候选的Advisors方法,AnnotationAwareAspectJAutoProxyCreator中重写的findCandidateAdvisors会调用这个方法
*/
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
// 具体的实现逻辑在advisorRetrievalHelper的findAdvisorBeans
return this.advisorRetrievalHelper.findAdvisorBeans();
} /**
* 获取可以应用到当前bean的Advisor
*/
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) { ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
// 获取可以应用到当前bean的Advisor
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
} finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
}

findCandidateAdvisors获取所有候选的Advisors

AOP使用的是的AnnotationAwareAspectJAutoProxyCreator类型的创建器,它重写了findCandidateAdvisors方法,方法的处理逻辑如下:

  • 调用了父类的findCandidateAdvisors方法获取候选的Advisors,也就是AbstractAdvisorAutoProxyCreator中实现的findCandidateAdvisors方法,这里的Advisors指的是本身是Advisor类型的bean。

  • 调用了buildAspectJAdvisors方法构建Advisors,具体的实现在BeanFactoryAspectJAdvisorsBuilder中, 这里的Advisors指的是使用了@AspectJ注解定义的切面,Spring会把它包装成Advisor。

/**
* AnnotationAwareAspectJAutoProxyCreator
*/
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
// Advisors构建工厂
@Nullable
private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder; @Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
// 如果为空使用ReflectiveAspectJAdvisorFactory
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
// 初始化BeanFactoryAspectJAdvisorsBuilder,这里使用的BeanFactoryAspectJAdvisorsBuilderAdapter
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
} protected List<Advisor> findCandidateAdvisors() {
// 1.调用父类的findCandidateAdvisors获取所有的Advisors,也就是AbstractAdvisorAutoProxyCreator中实现的findCandidateAdvisors方法
List<Advisor> advisors = super.findCandidateAdvisors();
if (this.aspectJAdvisorsBuilder != null) {
// 2.构建Advisors,具体实现在BeanFactoryAspectJAdvisorsBuilder中
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
} /**
* AbstractAdvisorAutoProxyCreator
* 它是实现了findCandidateAdvisors
*/
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
@Nullable
private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper; protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 使用的BeanFactoryAdvisorRetrievalHelperAdapter
this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
} /**
* 获取所有的候选Advisors
*
* @return the List of candidate Advisors
*/
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
// 获取候选的Advisor,具体的实现逻辑在advisorRetrievalHelper的findAdvisorBeans
return this.advisorRetrievalHelper.findAdvisorBeans();
}
}

1. findCandidateAdvisors获取候选的Advisors

findCandidateAdvisors方法具体的实现在BeanFactoryAdvisorRetrievalHelper中,它从beanFactory中获取了所有Advisor类型的bean

public class BeanFactoryAdvisorRetrievalHelper {
/**
* 在当前的bean工厂中查找所有Advisor类型的bean
*/
public List<Advisor> findAdvisorBeans() {
// 获取缓存的AdvisorBeanName
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
// 如果未获取到
if (advisorNames.length == 0) {
return new ArrayList<>();
}
List<Advisor> advisors = new ArrayList<>();
// 遍历所有的advisorNames
for (String name : advisorNames) {
if (isEligibleBean(name)) {
// 如果bean正在创建中
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
} else {
try {
// 从容器中获取实例,可以看到这里获取的是Advisor类型的bean
advisors.add(this.beanFactory.getBean(name, Advisor.class));
} catch (BeanCreationException ex) {
// 省略了异常处理
throw ex;
}
}
}
}
return advisors;
}
}

2. buildAspectJAdvisors构建Advisor

buildAspectJAdvisors在BeanFactoryAspectJAdvisorsBuilder中实现,这一步用于查找所有使用@AspectJ注解的bean,并将其包装成Advisor返回:

(1)从容器中获取所有的bean,调用isEligibleBean方法判断bean是否符合要求,如果符合进入下一步

(2)调用isAspect方法判断bean是否是一个切面,如果是进入下一步

(3)判断是否是单例模式

  • 如果是,创建BeanFactoryAspectInstanceFactory类型的工厂,调用AspectJAdvisorFactory的getAdvisors方法获取Advisor
  • 如果不是单例模式,创建PrototypeAspectInstanceFactory类型的工厂,调用AspectJAdvisorFactory的getAdvisors方法获取Advisor
public class BeanFactoryAspectJAdvisorsBuilder {

  	private final AspectJAdvisorFactory advisorFactory;

    /**
* 在当前bean工厂中查找所有使用@AspectJ注解的bean,并包装成Advisor返回
*/
public List<Advisor> buildAspectJAdvisors() {
// 获取所有的切面beanName
List<String> aspectNames = this.aspectBeanNames;
// 如果为空
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
// 从容器中获取所有的beanName
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
// 判断是否符合条件,BeanFactoryAspectJAdvisorsBuilderAdapter中实现
if (!isEligibleBean(beanName)) {
continue;
}
// 根据BeanName获取class类型
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
// 是否是切面
if (this.advisorFactory.isAspect(beanType)) {
// 添加到aspectNames
aspectNames.add(beanName);
// 创建Aspect元数据信息
AspectMetadata amd = new AspectMetadata(beanType, beanName);
// 单例模式
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
// 创建MetadataAwareAspectInstanceFactory
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 获取Advisor
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
} else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
} else {
// 原型模式
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
} if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
} else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
}
isEligibleBean的判断

BeanFactoryAspectJAdvisorsBuilderAdapter是AnnotationAwareAspectJAutoProxyCreator的内部类,它继承了BeanFactoryAspectJAdvisorsBuilder并重写了isEligibleBean方法:

public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {

    private class BeanFactoryAspectJAdvisorsBuilderAdapter extends BeanFactoryAspectJAdvisorsBuilder {

        @Override
protected boolean isEligibleBean(String beanName) {
// 调用isEligibleAspectBean
return AnnotationAwareAspectJAutoProxyCreator.this.isEligibleAspectBean(beanName);
}
} /**
* 校验给定的切面是否符合要求
*/
protected boolean isEligibleAspectBean(String beanName) {
if (this.includePatterns == null) {
return true;
}
else {
for (Pattern pattern : this.includePatterns) {
// 通过includePatterns进行匹配
if (pattern.matcher(beanName).matches()) {
return true;
}
}
return false;
}
}
}
isAspect的判断

前面在讲跳过代理对象的创建时已经看到isAspect的实现逻辑,如果使用了Aspect注解并且不是通过Ajc进行编译的,则判定为切面:

// AbstractAspectJAdvisorFactory
public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFactory { /**
* 是否是切面
*/
@Override
public boolean isAspect(Class<?> clazz) {
// 是否有Aspect注解并且不是通过Ajc编译的类
return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
} // 判断是否有Aspect注解
private boolean hasAspectAnnotation(Class<?> clazz) {
// 是否有Aspect注解
return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
} /**
* 是否通过Ajc编译
*/
private boolean compiledByAjc(Class<?> clazz) {
//
for (Field field : clazz.getDeclaredFields()) {
if (field.getName().startsWith(AJC_MAGIC)) {
return true;
}
}
return false;
}
}
AspectJAdvisorFactory获取Advisor

AspectJAdvisorFactory是一个Advisor工厂,它的继承关系如下:

AnnotationAwareAspectJAutoProxyCreator在初始化bean工厂的方法中,对AspectJAdvisorFactory进行了判断,则如果为空使用ReflectiveAspectJAdvisorFactory:

public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
// Advisors构建工厂
@Nullable
private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder; @Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
// 如果为空使用ReflectiveAspectJAdvisorFactory
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
// 初始化BeanFactoryAspectJAdvisorsBuilder
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
}

ReflectiveAspectJAdvisorFactory中实现了getAdvisor方法:

  1. getAdvisorMethods获取Advisor方法(也就是获取通知),具体是根据方法上是否有Pointcut注解来判断的,如果没有Pointcut注解则判定为是Advisor方法
  2. 调用getAdvisor方法将第1步中获取到的Advisor方法构建为Advisor对象
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
// 获取Aspect类信息
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
validate(aspectClass); // 装饰模式
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory); List<Advisor> advisors = new ArrayList<>();
// 获取Advisor方法,也就是获取没有使用@Pointcut注解的方法
for (Method method : getAdvisorMethods(aspectClass)) {
// 将方法构建为Advisor对象
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
} // If it's a per target aspect, emit the dummy instantiating aspect.
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
} // Find introduction fields.
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
} return advisors;
} // 获取Advisor方法,也就是获取切面中没有被使用Pointcut注解的方法
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
final List<Method> methods = new ArrayList<>();
ReflectionUtils.doWithMethods(aspectClass, method -> {
// 判断是否有Pointcut注解,如果没有则判定为是Advisor方法加入结果集中
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
methods.add(method);
}
}, ReflectionUtils.USER_DECLARED_METHODS);
if (methods.size() > 1) {
methods.sort(METHOD_COMPARATOR);
}
return methods;
}
}
构建Advisor的具体实现

ReflectiveAspectJAdvisorFactory的getAdvisor方法用于将方法封装为Advisor对象,可以看到第一个参数叫candidateAdviceMethod(候选的通知方法),上一步中传入的是获取到的Advisor方法,所以Spring中Advisor方法指的就是使用了通知注解的方法,getAdvisor方法主要做了如下操作:

  1. 构建AspectJExpressionPointcut切点表达式对象

    • 从通知方法上获取切面相关注解,具体是通过判断方法上是否有Pointcut、Around、Before、After、AfterReturning、AfterThrowing注解实现的
    • 从切面注解中获取设置的切点表达式,用于之后判断方法是否匹配使用,然后创建AspectJExpressionPointcut对象并设置获取到的切点表达式
  2. 将当前的Advisor方法、AspectJExpressionPointcut对象等信息封装为InstantiationModelAwarePointcutAdvisorImpl返回,它是一个Advisor
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {

    // 将Advisor方法构建为Advisor对象
@Override
@Nullable
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) { validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
// 获取切点
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
// 封装为InstantiationModelAwarePointcutAdvisorImpl
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
} // 获取切点表达式
@Nullable
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
// 获取AspectJ注解,具体是通过判断方法上是否有Pointcut、Around、Before、After、AfterReturning、AfterThrowing注解实现的
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
// 创建AspectJExpressionPointcut
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
// 设置切点表达式
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
if (this.beanFactory != null) {
ajexp.setBeanFactory(this.beanFactory);
}
return ajexp;
} } // AbstractAspectJAdvisorFactory
public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFactory { private static final Class<?>[] ASPECTJ_ANNOTATION_CLASSES = new Class<?>[]{
Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class}; /**
* 判断是否有AspectJ相关注解
*/
@SuppressWarnings("unchecked")
@Nullable
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
// 判断方法上是否有Pointcut、Around、Before、After、AfterReturning、AfterThrowing注解
for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
if (foundAnnotation != null) {
return foundAnnotation;
}
}
return null;
}
}

InstantiationModelAwarePointcutAdvisorImpl封装切面

InstantiationModelAwarePointcutAdvisorImpl是一个Adviosr,它对Aspect切面进行了封装,里面引用了Advice、Pointcut等切面相关信息,在构造函数的最后,调用了instantiateAdvice对通知进行增强处理,也就是根据不同的通知类型,将其包装为不同的Advice对象,具体的实现在ReflectiveAspectJAdvisorFactory中:

final class InstantiationModelAwarePointcutAdvisorImpl
implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation, Serializable {
// 切点表达式,用于匹配方法是否需要进行拦截
private final AspectJExpressionPointcut declaredPointcut; // 通知
private transient Method aspectJAdviceMethod; // AspectJAdvisorFactory
private final AspectJAdvisorFactory aspectJAdvisorFactory; private final MetadataAwareAspectInstanceFactory aspectInstanceFactory; private final int declarationOrder; // 切面名称
private final String aspectName; // 切点
private final Pointcut pointcut; private final boolean lazy; // 通知
@Nullable
private Advice instantiatedAdvice; @Nullable
private Boolean isBeforeAdvice; @Nullable
private Boolean isAfterAdvice; public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { this.declaredPointcut = declaredPointcut;
// 设置切面的类信息
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
// 设置方法名称
this.methodName = aspectJAdviceMethod.getName();
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
// 通知
this.aspectJAdviceMethod = aspectJAdviceMethod;
// AspectJAdvisorFactory
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
this.aspectInstanceFactory = aspectInstanceFactory;
this.declarationOrder = declarationOrder;
// 切面名称
this.aspectName = aspectName; if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Pointcut preInstantiationPointcut = Pointcuts.union(
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
this.pointcut = new PerTargetInstantiationModelPointcut(
this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
this.lazy = true;
} else {
// A singleton aspect.
this.pointcut = this.declaredPointcut;
this.lazy = false;
// 增强处理
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
} private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
// 调用ReflectiveAspectJAdvisorFactory获取Advice
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return (advice != null ? advice : EMPTY_ADVICE);
}
}

ReflectiveAspectJAdvisorFactory

ReflectiveAspectJAdvisorFactory中的getAdvice方法中可以看到对通知进行了判断,不同的通知使用不同的包装类:

  • 环绕通知,使用AspectJAroundAdvice
  • 前置通知,使用AspectJMethodBeforeAdvice
  • 后置通知,使用AspectJAfterAdvice
  • 返回通知,使用AspectJAfterReturningAdvice
  • 异常通知,使用AspectJAfterThrowingAdvice

public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {
@Override
@Nullable
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
// 获取AspectJAnnotation
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
} // 再次校验是否是切面
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: " +
"Offending method '" + candidateAdviceMethod + "' in class [" +
candidateAspectClass.getName() + "]");
} if (logger.isDebugEnabled()) {
logger.debug("Found AspectJ method: " + candidateAdviceMethod);
} AbstractAspectJAdvice springAdvice;
// 判断通知类型
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut: // 如果是一个切点
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround: // 环绕通知,使用AspectJAroundAdvice封装
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:// 前置通知,使用AspectJMethodBeforeAdvice
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:// 后置通知,使用AspectJAfterAdvice
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:// 返回通知,使用AspectJAfterReturningAdvice
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:// 异常通知,使用AspectJAfterThrowingAdvice
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
} // Now to configure the advice...
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings(); return springAdvice;
}
}

findAdvisorsThatCanApply获取可以应用到当前bean的Advisor

上一节中获取到了所有的Advisor,接下来要过滤出可以应用到当前bean的Advisor,findAdvisorsThatCanApply在AopUtils中实现:

public abstract class AopUtils {

    public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>();
for (Advisor candidate : candidateAdvisors) {
// 是否是IntroductionAdvisor并且canApply,加入到eligibleAdvisors中
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
// 再次遍历候选的Advisor
for (Advisor candidate : candidateAdvisors) {
// 如果是IntroductionAdvisor,上面已经对IntroductionAdvisor进行了处理,这里continue继续下一个
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
// 调用canApply方法判断
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
}

核心的逻辑在canApply方法中:

  • 根据切点Pointcut的getClassFilter方法对类进行匹配,判断targetClass目标类是否与切点匹配

  • 从切点获取MethodMatcher方法匹配器,通过MethodMatcher对目标类中的每一个方法进行匹配,也就是使用切点表达式对方法进行匹配,判断方法是否需要拦截。

public abstract class AopUtils {

    /**
* 是否可以应用到bean
*/
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
// 继续调用canApply
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
/**
* 是否可以应用到bean
*/
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
// 通过切点进行匹配,先判断类是否匹配
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
// 从切点中获取方法匹配器
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
// 如果是IntroductionAwareMethodMatcher
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
Set<Class<?>> classes = new LinkedHashSet<>();
if (!Proxy.isProxyClass(targetClass)) {
classes.add(ClassUtils.getUserClass(targetClass));
}
// 获取类的所有接口
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass)); for (Class<?> clazz : classes) {
// 获取类中的所有方法
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
// 遍历方法
for (Method method : methods) {
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) { // 调用方法的matches进行匹配
return true;
}
}
}
return false;
}
}

创建代理对象

上一节中已经获取到了可以应用到当前bean的Advisor,接下来就可以创建代理对象了,由于篇幅原因,创建代理的过程将另起一篇文章。

总结

参考

【猫吻鱼】Spring源码分析:全集整理

Spring版本:5.2.5.RELEASE

【Spring】AOP实现原理(二):Advisor获取的更多相关文章

  1. Spring AOP 实现原理

    什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...

  2. Spring框架系列(9) - Spring AOP实现原理详解之AOP切面的实现

    前文,我们分析了Spring IOC的初始化过程和Bean的生命周期等,而Spring AOP也是基于IOC的Bean加载来实现的.本文主要介绍Spring AOP原理解析的切面实现过程(将切面类的所 ...

  3. Spring框架系列(10) - Spring AOP实现原理详解之AOP代理的创建

    上文我们介绍了Spring AOP原理解析的切面实现过程(将切面类的所有切面方法根据使用的注解生成对应Advice,并将Advice连同切入点匹配器和切面类等信息一并封装到Advisor).本文在此基 ...

  4. Spring框架系列(11) - Spring AOP实现原理详解之Cglib代理实现

    我们在前文中已经介绍了SpringAOP的切面实现和创建动态代理的过程,那么动态代理是如何工作的呢?本文主要介绍Cglib动态代理的案例和SpringAOP实现的原理.@pdai Spring框架系列 ...

  5. Spring框架系列(12) - Spring AOP实现原理详解之JDK代理实现

    上文我们学习了SpringAOP Cglib动态代理的实现,本文主要是SpringAOP JDK动态代理的案例和实现部分.@pdai Spring框架系列(12) - Spring AOP实现原理详解 ...

  6. 何为代理?jdk动态代理与cglib代理、spring Aop代理原理浅析

    原创声明:本博客来源为本人原创作品,绝非他处摘取,转摘请联系博主 代理(proxy)的定义:为某对象提供代理服务,拥有操作代理对象的功能,在某些情况下,当客户不想或者不能直接引用另一个对象,而代理对象 ...

  7. jdk动态代理与cglib代理、spring Aop代理原理-代理使用浅析

    原创声明:本博客来源为本人原创作品,绝非他处摘取,转摘请联系博主 代理(proxy)的定义:为某对象提供代理服务,拥有操作代理对象的功能,在某些情况下,当客户不想或者不能直接引用另一个对象,而代理对象 ...

  8. 【Spring】Spring AOP实现原理

    Spring AOP实现原理 在之前的一文中介绍过Spring AOP的功能使用,但是没有深究AOP的实现原理,今天正好看到几篇好文,于是就自己整理了一下AOP实现的几种方式,同时把代理模式相关知识也 ...

  9. Spring AOP实现方式二【附源码】

    自动代理模式[和我们说的方式一 配置 和 测试调用不一样哦~~~]  纯POJO切面 源码结构: 1.首先我们新建一个接口,love 谈恋爱接口. package com.spring.aop; /* ...

  10. Spring Aop底层原理详解

    Spring Aop底层原理详解(来源于csdn:https://blog.csdn.net/baomw)

随机推荐

  1. python---十进制转换成n进制

    """ 十进制转换成n进制 例子: 100转换成8进制-----144 256除8 商32 余0 32除8 商4 余0 4除8 商0 余4 每次结果的余数进栈, 最后出栈 ...

  2. Docker的简介

    前言 Docker 是 PaaS 提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上, 基于go语言并遵从Apache2.0协议开源. 何为Docker? ...

  3. 攻防世界 favorite_number

    favorite_number 进入环境得到源码 <?php //php5.5.9 $stuff = $_POST["stuff"]; $array = ['admin', ...

  4. 【分享汇总】25个主题分享,360°领略OpenHarmony最新技术版图

    2021年10月,开放原子开源基金会旗下开源项目 OpenAtom OpenHarmony (以下简称"OpenHarmony") 应邀参加华为2021 HDC 开发者大会,并组织 ...

  5. Codeforces Round #704 (Div. 2), problem: (C) Maximum width还是要多学习

    Problem - C - Codeforces 看清题目要求, 最重要部分在第二段. 大佬最后给出的代码果然简单, 思路简单化, 未必非要把答案在一个大括号里全部完成, 两个指针同时跑,中间加了一堆 ...

  6. 2021.07.23 P3275 糖果(差分约束)

    2021.07.23 P3275 糖果(差分约束) [P3275 SCOI2011]糖果 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.为了满足更多更多约束条件,合适地 ...

  7. Android 12(S) 图像显示系统 - 基础知识之 BitTube

    必读: Android 12(S) 图像显示系统 - 开篇 一.基本概念 在Android显示子系统中,我们会看到有使用BitTube来进行跨进程数据传递.BitTube的实现很简洁,就是一对&quo ...

  8. pta L2-002 链表去重 +散列表知识小普及+二进制取反补码运算

    题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805072641245184: 废话:今天忙着学习新知识了,没怎 ...

  9. iOS全埋点解决方案-手势采集

    前言 ​ 随着科技以及业务的发展,手势的应用也越来越普及,因此对于数据采集,我们要考虑如果通过全埋点来实现手势的采集. 一.手势识别器 ​ 苹果为了降低开发者在手势事件处理方面的开发难度,定义了一个抽 ...

  10. Istio实践(3)- 路由控制及多应用部署(netcore&springboot)

    前言:接上一篇istio应用部署及服务间调用,本文介绍通过构建.netcore与springboot简单服务应用,实现服务间调用及相关路由控制等 1..netcore代码介绍及应用部署 新建.netc ...