public class Handler {
public int handle() {
return 1;
}
}
创建切面
@Aspect
@Component
@Slf4j
public class LogAspect {
@Pointcut("execution(public int com.example.demo.handler.Handler.*(..))")
public void pointcut() {};
@Before("pointcut()")
public void logBefore() {
log.info("log before");
}
@After("pointcut()")
public void logAfter() {
log.info("log after");
}
}
增加配置
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AspectConfiguration {
@Bean
public Handler handler() {
return new Handler();
}
@Bean
public LogAspect logAspect() {
return new LogAspect();
}
}
运行
此时后台会打印
log before
log after
概念理解 Joinpoint程序中的执行点,常见的有如下几种
- 方法调用
- 方法调用执行
- 构造方法调用
- 构造方法调用执行
- 字段设置
- 字段获取
- 异常处理执行
- 类初始化
调用和调用执行的区别
在spring aop中,仅支持方法调用执行类型的Joinpoint
用来选择一些Joinpoint的表达式
下面是Java中对该概念的实现
public interface Pointcut {
ClassFilter getClassFilter();
MethodMatcher getMethodMatcher();
Pointcut TRUE = TruePointcut.INSTANCE;
}
ClassFilter用来过滤类,MethodMatcher用来过滤方法
public interface ClassFilter {
boolean matches(Class> clazz);
ClassFilter TRUE = TrueClassFilter.INSTANCE;
}
public interface MethodMatcher {
// 只对方法的名称进行过滤
boolean matches(Method method, Class> targetClass);
// 当返回true时,代表是动态的,此时会顺序执行两个参数版本的match和三个参数版本的match,只有都返回true才会进行增强
// 当返回false时,代表是静态的,此时只会执行两个参数版本的match
boolean isRuntime();
// 不仅对方法的名称进行顾虑,而且会对方法的参数进行过滤
boolean matches(Method method, Class> targetClass, Object... args);
MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;
}
根据isRuntime的返回值,MethodMatcher又分为静态的StatisMethodMatcher和动态的DynamicMethodMatcher
下面是常见的几种PointCut
- NameMatchMethodPointcut 通过方法的名称来进行匹配
- JdkRegexpMethodPointcut 通过正则表达是来进行匹配
- AnnotationMatchingPointcut 通过是否使用指定的注解来进行匹配
- ComposablePointcut 组合多个Pointcut
在Joinpoint执行的具体增强逻辑,一共有如下几种类型
- Before Advice
在Joinpoint之前执行 - After Advice
在Joinpoint之后执行 - After returning Advice
在Joinpoint正常返回之后执行 - After throwing Advice
在Joinpoint抛出异常时执行 - After Advice
在Joinpoint执行完毕之后执行,不管是否正常执行 - Around Advice
在Joinpoint执行之前和之后执行 - Introduction
不同于其他Advice,为指定对象添加新的行为
IntroductionInterceptor用来实现Introduction
MethodInterceptor相当于AroundAdvice
用来组合PointCut和Advice,即指定在哪些执行点执行哪些增强逻辑
用来实现AOP中的Aspect,但是两者还是有些地方不同
Advisor中只能有一个Pointcut和一个Advice,而Aspect可以有多个Pointcut和多个Advice
Advisor主要分为两类:PointcutAdvisor和IntroductionAdvisor
@import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
该注解的主要作用就是通过@import注解引入AspectJAutoProxyRegistrar
AspectJAutoProxyRegistrarclass AspectJAutoProxyRegistrar implements importBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
Annotationmetadata importingClassmetadata, BeanDefinitionRegistry registry) {
// 注册一个AspectJAnnotationAutoProxyCreator
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
// 获取注解信息
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassmetadata, EnableAspectJAutoProxy.class);
// 将注解上的信息设置到之前注册的bean上
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
registerAspectJAnnotationAutoProxyCreatorIfNecessary
向容器中注册一个AnnotationAwareAspectJAutoProxyCreator
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
private static BeanDefinition registerOrEscalateApcAsRequired(Class> cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
// 判断容器中是否有名称为org.springframework.aop.config.internalAutoProxyCreator的bean
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
// 当前容器中已经存在名称为org.springframework.aop.config.internalAutoProxyCreator的bean
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
// 已有bean的类型和当前需要注册的类不同
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
// 确定两个类的优先级
// InfrastructureAdvisorAutoProxyCreator < AspectJAwareAdvisorAutoProxyCreator < AnnotationAwareAspectJAutoProxyCreator
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
// 将bean的类型设置为优先级最高的类型
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
// 不存在名为org.springframework.aop.config.internalAutoProxyCreator的bean
// 创建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;
}
forceAutoProxyCreatorToUseClassProxying
该方法修改了beanDefinition,将proxyTargetClass设置为true
public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
}
}
forceAutoProxyCreatorToExposeProxy
该方法修改了beanDefinition,将exposeProxy设置为true
public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
}
}
AnnotationAwareAspectJAutoProxyCreator
看下类继承结构
首先看下AbstractAutoProxyCreator,其实现了SmartInstantiationAwareBeanPostProcessor
这里主要看下postProcessBeforeInstantiation
在每个bean实例化之前进行拦截,判断是否有处理当前bean的TargetSource,如果有会创建该TargetSource,将TargetSource作为被代理的对象,然后执行增强,并返回
public Object postProcessBeforeInstantiation(Class> beanClass, String beanName) throws BeansException {
// 获取缓存key
Object cacheKey = getCacheKey(beanClass, beanName);
// 如果beanName为null或者不在targetSourcedBean中
if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
// advisedBeans存放已经经过切面处理或者判断为不需要进行切面处理的bean
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
// 判断不需要进行增强,以下两种情况不需要进行增强
// isInfrastructureClass用来判断当前类是否是aop相关的基础类,比如Advice、Pointcut、Advisor、AopInfrastructureBean
// shouldSkip会被子类重写
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
// 标志为不需要进行增强
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
if (beanName != null) {
// 判断是否需要对当前bean创建targetSource
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
// 判断为需要创建targetSource
// 将当前bean标记为经过targetSource的处理
this.targetSourcedBeans.add(beanName);
// 获取当前适用于当前bean的advice和advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
// 创建代理对象
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
return null;
}
获取缓存key,针对bean的类型,生成真实的beanName
protected Object getCacheKey(Class> beanClass, String beanName) {
// 判断是否是FactoryBean,如果是的话会在beanName之前加上&
if (StringUtils.hasLength(beanName)) {
return (FactoryBean.class.isAssignableFrom(beanClass) ?
BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
}
else {
return beanClass;
}
}
postProcessAfterInitialization
在所有bean初始化完成之后进行拦截,判断当前bean是否需要增强
这里不会对在postProcessBeforeInstantiation中创建过TargetSource并进行过增强的bean再进行一次处理
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
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) {
// 该bean已经在创建targetSource时进行过代理操作,直接返回
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 当前bean不需要进行增强
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 当前bean是aop基础类或者认为需要跳过
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
// 获取适用于当前bean的增强逻辑
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
// 有增强逻辑
// 将当前bean标志为已经被增强
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理
// 可以看到这里也会为初始化后的bean创建一个SingletonTargetSource
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;
}
createProxy
protected Object createProxy(
Class> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
// 将beanDefinition中的originalTargetClass属性设置为beanClass
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 读取当前有关aop的配置,设置到ProxyFactory中
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
// 当前proxyTargetClass配置设置为false,代表不启用cglib代理
if (!proxyFactory.isProxyTargetClass()) {
// 判断当前bean需要使用proxyTargetClass
// 当beanDefinition的preserveTargetClass属性设置为true时会判断为需要使用cglib代理
if (shouldProxyTargetClass(beanClass, beanName)) {
// 将proxyFactory的proxyTargetClass设置为true
proxyFactory.setProxyTargetClass(true);
}
else {
// 判断是否有有效接口,如果没有,那么切换到使用cglib来生成代理
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 将interceptor转换成advisor,设置到ProxyFactory中
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 创建代理对象,具体过程可以看到另外一篇文章https://editor.csdn.net/md/?articleId=98391083
return proxyFactory.getProxy(getProxyClassLoader());
}
evaluateProxyInterfaces
protected void evaluateProxyInterfaces(Class> beanClass, ProxyFactory proxyFactory) {
// 获取当前bean实现的所有接口,包括父类实现的接口
Class>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
boolean hasReasonableProxyInterface = false;
for (Class> ifc : targetInterfaces) {
// 判断是否是有效接口,需要通过以下三个规则校验
// 不是spring中的回调接口,比如InitializingBean ,DisposableBean等
// 不是内部接口,比如GroovyObject, 以.cglib.proxy.Factory结尾的类等
// 接口中有方法
if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
ifc.getMethods().length > 0) {
hasReasonableProxyInterface = true;
break;
}
}
// 具有有效接口,将接口添加到proxyFactory中
if (hasReasonableProxyInterface) {
// Must allow for introductions; can't just set interfaces to the target's interfaces only.
for (Class> ifc : targetInterfaces) {
proxyFactory.addInterface(ifc);
}
}
else {
// 没有有效接口,设置为使用cglib代理
proxyFactory.setProxyTargetClass(true);
}
}
buildAdvisors
protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors) {
// Handle prototypes correctly...
// 默认情况下是空
Advisor[] commonInterceptors = resolveInterceptorNames();
// 合并commonInterceptors和添加的interceptor
List
AbstractAdvisorAutoProxyCreator
getAdvicesAndAdvisorsForBean
下面看下如何找到当前bean需要使用的Advisor
protected Object[] getAdvicesAndAdvisorsForBean(Class> beanClass, String beanName, TargetSource targetSource) {
List advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
protected ListAnnotationAwareAspectJAutoProxyCreatorfindEligibleAdvisors(Class> beanClass, String beanName) { // 从容器中获取Advisor类型的bean,AnnotationAwareAspectJAutoProxyCreator会重写这部分逻辑 List candidateAdvisors = findCandidateAdvisors(); // 选择需要应用到当前bean的增强 List eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); // 钩子方法,子类可以重写这个方法,来增强额外的advisor extendAdvisors(eligibleAdvisors); // 对Advisor进行排序 if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }
通过上面的源码我们了解到,spring会从容器中获取Advisor类型的bean,然后将能够应用到当前bean的Advisor挑选出来,设置到ProxyFactory,ProxyFactory在生成代理对象的时候,会使用这些Advisor
那么我们通过@Aspect注解声明的Advisor又是如何注入到容器中的呢,这些Advisor并没有实现Advisor接口
AnnotationAwareAspectJAutoProxyCreator会完成这些工作
AbstractAdvisorAutoProxyCreator实现了BeanFactoryAware
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException(
"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
}
initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}
AnnotationAwareAspectJAutoProxyCreator重写了initBeanFactory
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
findCandidateAdvisors
接着看下AnnotationAwareAspectJAutoProxyCreator是如何重写findCandidateAdvisors的
protected ListfindCandidateAdvisors() { // Add all the Spring advisors found according to superclass rules. // 从容器中获取Advisor类型的bean List advisors = super.findCandidateAdvisors(); // Build Advisors for all AspectJ aspects in the bean factory. // 解析使用了@Aspect注解的类 advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); return advisors; }
先看下super.findCandidateAdvisors,会调用AbstractAdvisorAutoProxyCreator的findCandidateAdvisors
// AbstractAdvisorAutoProxyCreator protected ListfindCandidateAdvisors() { return this.advisorRetrievalHelper.findAdvisorBeans(); }
// BeanFactoryAdvisorRetrievalHelper public ListfindAdvisorBeans() { // Determine list of advisor bean names, if not cached already. String[] 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! // 从容器中获取Advisor类型的bean advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Advisor.class, true, false); this.cachedAdvisorBeanNames = advisorNames; } if (advisorNames.length == 0) { return new ArrayList (); } List advisors = new ArrayList (); 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; if (this.beanFactory.isCurrentlyInCreation(bce.getBeanName())) { 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; }
上述方法的主要作用就是从容器中取出Advisor类型的bean
接着看下AspectJAdvisorsBuilder的buildAspectJAdvisors
public ListbuildAspectJAdvisors() { List aspectNames = this.aspectBeanNames; if (aspectNames == null) { synchronized (this) { aspectNames = this.aspectBeanNames; if (aspectNames == null) { List advisors = new linkedList (); aspectNames = new linkedList (); // 从容器中取出所有bean的名称 String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Object.class, true, false); for (String beanName : beanNames) { if (!isEligibleBean(beanName)) { continue; } // We must be careful not to instantiate beans eagerly as in this case they // would be cached by the Spring container but would not have been weaved. // 获取bean的类型 Class> beanType = this.beanFactory.getType(beanName); if (beanType == null) { continue; } // 判断是否使用了@Aspect注解 if (this.advisorFactory.isAspect(beanType)) { aspectNames.add(beanName); Aspectmetadata amd = new Aspectmetadata(beanType, beanName); // 根据aspect不同的实例化模式,实例化aspect if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { metadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); List 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 { // Per target or per this. 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 advisors = new linkedList (); for (String aspectName : aspectNames) { List 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; }



