IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring Boot源码简析 @Aspect -> 正文阅读

[Java知识库]Spring Boot源码简析 @Aspect

相关阅读

简介

本文基于SpringBoot 2.6.2对@Aspect注解的使用进行源码分析。

Demo

依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

源码

业务接口及实现

public interface IDemoService {

    String method();
}


@Service
@Slf4j
public class DemoServiceImpl implements IDemoService {

    @Override
    public String method() {
        log.info("do something...");
        return "method's result";
    }
}

切面逻辑

@Aspect
@Component
@Slf4j
public class LogAspect {

    @Pointcut(value = "execution(* xing.demo.springaop.demo.*.*(..))")
    public void pointcut() {
    }

    /**
     * 前置通知,目标方法之前执行
     *
     * @param joinPoint 连接点,可以声明一个类型为JoinPoint的参数,从而注入被切入的方法的信息
     */
    @Before(value = "pointcut()")
    public void before(JoinPoint joinPoint) {
        log.info("Before {}", joinPoint.getSignature().getName());
    }

    /**
     * 后置通知,目标方法之后执行,无论目标方法正常返回或者异常退出都会执行
     *
     * @param joinPoint 连接点,可以声明一个类型为JoinPoint的参数,从而注入被切入的方法的信息
     */
    @After(value = "pointcut()")
    public void after(JoinPoint joinPoint) {
        log.info("After {}", joinPoint.getSignature().getName());
    }

    /**
     * 返回后通知,目标方法正常返回后执行
     *
     * @param joinPoint 连接点,可以声明一个类型为JoinPoint的参数,从而注入被切入的方法的信息
     */
    @AfterReturning(value = "pointcut()", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        log.info("AfterReturning {}", joinPoint.getSignature().getName());
        log.info("AfterReturning JoinPoint's result is : {}", result);
    }

    /**
     * 异常通知,目标方法发生指定异常(方法入参)退出后执行
     *
     * @param joinPoint 连接点,可以声明一个类型为JoinPoint的参数,从而注入被切入的方法的信息
     */
    @AfterThrowing(value = "pointcut()", throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, IllegalArgumentException e) {
        log.info("AfterThrowing {}", joinPoint.getSignature().getName());
        log.info("AfterThrowing Throwable is : {}", e.getMessage());
    }

    /**
     * 环绕通知
     * 方法需要有返回结果,可以直接返回目标方法执行的结果,也可以返回基于目标方法执行结果的逻辑处理后结果
     * @param joinPoint 连接点类型必须为ProceedingJoinPoint,允许控制何时执行,是否执行连接点
     * @return 返回值
     */
    @Around(value = "pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("Around before {}", joinPoint.getSignature().getName());
        Object result;
        try {
            // 执行连接点
            result = joinPoint.proceed();
        } catch (Throwable e) {
            log.info("Around Throwable : {}", e.getMessage());
            return null;
        }
        log.info("Around after {}", joinPoint.getSignature().getName());
        log.info("Around JoinPoint's result is : {}", result);

        // 返回连接点的返回结果
        return result;
    }
}

测试

代码

@SpringBootTest
class DemoServiceTest {

    @Autowired
    private DemoServiceImpl demoService;

    @Test
    void test() {
        demoService.method();
    }
}

测试结果

  1. 正常退出
    方法实现如下:
@Override
public String method() {
    log.info("do something...");
    return "method's result";
}

结果如下:

Around before method
Before method
do something...
AfterReturning method
AfterReturning JoinPoint's result is : method's result
After method
Around after method
Around JoinPoint's result is : method's result
  1. 异常退出且匹配异常通知方法
    方法实现如下:
@Override
public String method() {
    log.info("do something...");
    throw new IllegalArgumentException("Invalid argument");
}

结果如下:

Around before method
Before method
do something...
AfterThrowing method
AfterThrowing Throwable is : Invalid argument
After method
Around Throwable : Invalid argument
  1. 异常退出且未匹配异常通知方法
    方法实现如下:
@Override
public String method() {
    log.info("do something...");
    throw new IllegalStateException("Invalid state");
}

结果如下:

Around before method
Before method
do something...
After method
Around Throwable : Invalid state

简析

自动配置

通过依赖spring-boot-starter-aop,会引入如下依赖:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>5.3.14</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.7</version>
    <scope>compile</scope>
</dependency>

SpringBoot的自动配置模块会根据spring-boot-autoconfigure-2.6.2.jar下的spring.factories文件自动引入自动配置类XxxAutoConfiguration,其中就包括org.springframework.boot.autoconfigure.aop.AopAutoConfiguration

AopAutoConfiguration

简介
AopAutoConfiguration完成了Spring AOP的自动配置功能;支持设置配置项spring.aop.auto来开启(true,默认值)或者关闭(false)自动配置;支持设置配置项spring.aop.proxy-target-class来表示使用CGLIB代理(true,默认值)还是JDK动态代理(false);

源码

@Configuration(proxyBeanMethods = false)
// 除非明确配置spring.aop.auto=false,否则开启AOP自动配置
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {

    @Configuration(proxyBeanMethods = false)
    // 存在org.aspectj.weaver.Advice则生效
    // 因为存在org.aspectj.aspectjweaver依赖,故org.aspectj.weaver.Advice存在
    @ConditionalOnClass(Advice.class)
    static class AspectJAutoProxyingConfiguration {

        @Configuration(proxyBeanMethods = false)
        // 引入EnableAspectJAutoProxy,开启@Aspect注解驱动的自动代理的功能,且使用JDK动态代理
        @EnableAspectJAutoProxy(proxyTargetClass = false)
        // 若配置spring.aop.proxy-target-class=false,则生效
        @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false")
        static class JdkDynamicAutoProxyConfiguration {

        }

        @Configuration(proxyBeanMethods = false)
        // 引入EnableAspectJAutoProxy,开启@Aspect注解驱动的自动代理的功能,且使用CGLIB代理
        @EnableAspectJAutoProxy(proxyTargetClass = true)
        // 除非明确配置spring.aop.proxy-target-class=false,否则生效
        @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
        static class CglibAutoProxyConfiguration {

        }
    }

    @Configuration(proxyBeanMethods = false)
    // 不存在org.aspectj.weaver.Advice则生效
    @ConditionalOnMissingClass("org.aspectj.weaver.Advice")
    // 除非明确配置spring.aop.proxy-target-class=false,否则生效
    @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
    static class ClassProxyingConfiguration {

        @Bean
        static BeanFactoryPostProcessor forceAutoProxyCreatorToUseClassProxying() {
            return (beanFactory) -> {
                if (beanFactory instanceof BeanDefinitionRegistry) {
                    BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
                    AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
                    AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
                }
            };
        }

    }
}

由于配置文件中未设置配置项spring.aop.auto,则存在依赖org.aspectj.aspectjweaver,所以AopAutoConfiguration.AspectJAutoProxyingConfiguration会生效,又因为配置文件中未设置配置项spring.aop.proxy-target-class,所以AopAutoConfiguration.AspectJAutoProxyingConfiguration.CglibAutoProxyConfiguration会生效,引入@EnableAspectJAutoProxy,且其proxyTargetClass为true,表示使用CGLIB代理;

EnableAspectJAutoProxy

简介
@EnableAspectJAutoProxy表示开启@Aspect注解驱动的自动代理的功能,即向容器添加自动代理创建器AnnotationAwareAspectJAutoProxyCreator,详见Spring Boot源码简析 @EnableAspectJAutoProxy

切面解析

这块主要分析被@Aspect标注的类的通知方法是如何转换为Advisor
AnnotationAwareAspectJAutoProxyCreator重写了父类AbstractAdvisorAutoProxyCreatorfindCandidateAdvisors方法,代码如下:

protected List<Advisor> findCandidateAdvisors() {
    // 调用父类方法获取已有的Advisor集合
    List<Advisor> advisors = super.findCandidateAdvisors();
    if (this.aspectJAdvisorsBuilder != null) {
        // 增加额外的Aspect Advisor
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    }
    return advisors;
}

AnnotationAwareAspectJAutoProxyCreator的属性aspectJAdvisorsBuilder使用的是BeanFactoryAspectJAdvisorsBuilderAdapter

BeanFactoryAspectJAdvisorsBuilderAdapter

buildAspectJAdvisors方法代码如下:

public List<Advisor> buildAspectJAdvisors() {
    List<String> aspectNames = this.aspectBeanNames;

    // 如果还未解析过@Aspect标注的类,则需要解析
    if (aspectNames == null) {
        synchronized (this) {
            aspectNames = this.aspectBeanNames;
            // Double Check
            if (aspectNames == null) {
                // 开始解析

                List<Advisor> advisors = new ArrayList<>();
                aspectNames = new ArrayList<>();
                // 获取容器中所有的beanName
                String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                        this.beanFactory, Object.class, true, false);
                // 遍历beanName
                for (String beanName : beanNames) {
                    if (!isEligibleBean(beanName)) {
                        // 若不符合,则跳过
                        // 默认实现都符合,子类可重写以实现额外处理逻辑
                        continue;
                    }
                    Class<?> beanType = this.beanFactory.getType(beanName, false);
                    if (beanType == null) {
                        continue;
                    }
                    
                    // 判断是否被标注@Aspect
                    if (this.advisorFactory.isAspect(beanType)) {
                        // 找到被@Aspect标注的bean,则缓存该beanName
                        aspectNames.add(beanName);
                        AspectMetadata amd = new AspectMetadata(beanType, beanName);
                        if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                            // 如果是单例,则通知方法是通用的
                            MetadataAwareAspectInstanceFactory factory =
                                    new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                            // 解析该bean的所有通知方法,并包装为Advisor
                            List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                            if (this.beanFactory.isSingleton(beanName)) {
                                // bean是单例,表示Advisor可通用,则缓存所有Advisor
                                this.advisorsCache.put(beanName, classAdvisors);
                            }
                            else {
                                // bean是多例,表示Advisor需要每次生成,则缓存该factory
                                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);
                            // 缓存该factory
                            this.aspectFactoryCache.put(beanName, factory);
                            // 解析该bean的所有通知方法,并包装为Advisor
                            advisors.addAll(this.advisorFactory.getAdvisors(factory));
                        }
                    }
                }
                // 缓存解析结果
                this.aspectBeanNames = aspectNames;
                return advisors;
            }
        }
    }

    if (aspectNames.isEmpty()) {
        // 不存在@Aspect标注的类,则无通知方法
        return Collections.emptyList();
    }
    List<Advisor> advisors = new ArrayList<>();
    // 遍历缓存的@Aspect标注的beanName
    for (String aspectName : aspectNames) {
        List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
        if (cachedAdvisors != null) {
            // 存在缓存的Advisor则表示为单例,可以直接使用
            advisors.addAll(cachedAdvisors);
        }
        else {
            // 不存在,则需要每次重新生成
            MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
            advisors.addAll(this.advisorFactory.getAdvisors(factory));
        }
    }
    return advisors;
}

其中this.advisorFactory.getAdvisors(factory)负责将Aspect类型注解标注的通知方法变成Advisor,其this.advisorFactoryReflectiveAspectJAdvisorFactory

ReflectiveAspectJAdvisorFactory

getAdvisors方法代码如下:

public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
    Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
    String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
    validate(aspectClass);

    MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
            new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

    List<Advisor> advisors = new ArrayList<>();
    // 遍历所有通知方法,即非@Pointcut标注的,非源自Object的方法
    for (Method method : getAdvisorMethods(aspectClass)) {
        // 将通知方法转换为Advisor
        Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
        if (advisor != null) {
            // 转换成功则添加该Advisor
            advisors.add(advisor);
        }
    }

    if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
        Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
        advisors.add(0, instantiationAdvisor);
    }

    // 查找引介通知
    for (Field field : aspectClass.getDeclaredFields()) {
        Advisor advisor = getDeclareParentsAdvisor(field);
        if (advisor != null) {
            // 存在则添加该Advisor
            advisors.add(advisor);
        }
    }

    return advisors;
}

public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
        int declarationOrderInAspect, String aspectName) {

    validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());

    // 获取Pointcut表达式
    AspectJExpressionPointcut expressionPointcut = getPointcut(
            candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
    if (expressionPointcut == null) {
        // 不存在则不是通知方法
        return null;
    }

    // 将通知方法包装为InstantiationModelAwarePointcutAdvisorImpl
    return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
            this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}

InstantiationModelAwarePointcutAdvisorImplinstantiateAdvice方法会根据AspectJExpressionPointcut获取到真正的Advice,代码如下:

private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
    Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
            this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
    return (advice != null ? advice : EMPTY_ADVICE);
}

使用this.aspectJAdvisorFactoryReflectiveAspectJAdvisorFactory,将方法包装为Advice,其getAdvice代码如下:

public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
        MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

    Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
    validate(candidateAspectClass);

    // 获取通知方法上的Aspect类型注解
    AspectJAnnotation<?> aspectJAnnotation =
            AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
    if (aspectJAnnotation == null) {
        return null;
    }

    // 校验当前方法所在的类是否被@Aspect标注
    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;
    // 根据Aspect注解类型,包装为对应的Advice
    switch (aspectJAnnotation.getAnnotationType()) {
        case AtPointcut:
            if (logger.isDebugEnabled()) {
                logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
            }
            return null;
        case AtAround:
            springAdvice = new AspectJAroundAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtBefore:
            springAdvice = new AspectJMethodBeforeAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtAfter:
            springAdvice = new AspectJAfterAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtAfterReturning:
            springAdvice = new AspectJAfterReturningAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
            if (StringUtils.hasText(afterReturningAnnotation.returning())) {
                springAdvice.setReturningName(afterReturningAnnotation.returning());
            }
            break;
        case AtAfterThrowing:
            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);
    }

    springAdvice.setAspectName(aspectName);
    springAdvice.setDeclarationOrder(declarationOrder);
    String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
    if (argNames != null) {
        springAdvice.setArgumentNamesFromStringArray(argNames);
    }
    springAdvice.calculateArgumentBindings();

    return springAdvice;
}

至此,@Aspect标注的类中的通知方法转化为Advisor的分析就结束了;

代理创建

这块主要分析实例是如何被代理的;
AnnotationAwareAspectJAutoProxyCreator继承自AbstractAutoProxyCreatorAbstractAutoProxyCreator实现了SmartInstantiationAwareBeanPostProcessor接口,所以AnnotationAwareAspectJAutoProxyCreator可以在Bean实例之前做处理,比如创建代理来替换原Bean;

AbstractAutoProxyCreator实现了postProcessAfterInitialization方法,核心代码如下:

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            // 如果该Bean存在相应的Advisor的话,则代理
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
        // TargetSource无需包装
        return 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的拦截器,如果为null则无需代理
    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;
}

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();
}

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    // 获取BeanFactory中所有的Advisor Bean
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    // 获取可以应用到指定Bean的Advisor Bean
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    // 扩展Advisor
    extendAdvisors(eligibleAdvisors);
    if (!eligibleAdvisors.isEmpty()) {
        // 排序
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    }
    return eligibleAdvisors;
}

protected List<Advisor> findCandidateAdvisors() {
    Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
    // 借助BeanFactoryAdvisorRetrievalHelper实现获取BeanFactory中所有的Advisor Bean
    return this.advisorRetrievalHelper.findAdvisorBeans();
}

protected List<Advisor> findAdvisorsThatCanApply(
        List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

    ProxyCreationContext.setCurrentProxiedBeanName(beanName);
    try {
        // 借助AopUtils获取可以应用到指定Bean的Advisor Bean
        return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
    }
    finally {
        ProxyCreationContext.setCurrentProxiedBeanName(null);
    }
}

切面解析中提到,AnnotationAwareAspectJAutoProxyCreator重写了父类AbstractAdvisorAutoProxyCreatorfindCandidateAdvisors方法,支持@Aspect标注的类中的通知方法转化的Advisor,所以只要满足Aspect注解中的pointcut表达式的方法所在的类都会被代理;
AbstractAutoProxyCreator.createProxy实现了代理创建,其核心代码如下:

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
        @Nullable 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 (Proxy.isProxyClass(beanClass)) {
            for (Class<?> ifc : beanClass.getInterfaces()) {
                proxyFactory.addInterface(ifc);
            }
        }
    }
    else {
        // 未设置proxyTargetClass标识,则进行默认检查
        if (shouldProxyTargetClass(beanClass, beanName)) {
            // 设置proxyTargetClass标识
            proxyFactory.setProxyTargetClass(true);
        }
        else {
            // 评估是否有可用的代理接口
            evaluateProxyInterfaces(beanClass, proxyFactory);
        }
    }

    // 根据通用拦截器和特定拦截器创建Advisor
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    proxyFactory.addAdvisors(advisors);
    proxyFactory.setTargetSource(targetSource);
    // 可由子类实现定制化处理
    customizeProxyFactory(proxyFactory);

    proxyFactory.setFrozen(this.freezeProxy);
    if (advisorsPreFiltered()) {
        // 设置preFiltered标识,表示拦截器都有效
        proxyFactory.setPreFiltered(true);
    }

    // Use original ClassLoader if bean class not locally loaded in overriding class loader
    ClassLoader classLoader = getProxyClassLoader();
    if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
        classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
    }
    // 通过ProxyFactory创建代理
    return proxyFactory.getProxy(classLoader);
}

ProxyFactory.getProxy方法的核心代码如下:

public Object getProxy(@Nullable ClassLoader classLoader) {
    return createAopProxy().getProxy(classLoader);
}

其中createAopProxy()最终由DefaultAopProxyFactory实现,核心代码如下:

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    if (!NativeDetector.inNativeImage() &&
            (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
        // 1. 设置`optimize`标识;
        // 2. 设置`proxyTargetClass`标识;
        // 3. 没有指定任何代理接口;
        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)) {
            // 如果目标对象为接口类型或者目标对象类型为动态代理类,则使用JDK动态代理
            return new JdkDynamicAopProxy(config);
        }
        // 否则使用CGLIB代理
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        // 使用JDK动态代理
        return new JdkDynamicAopProxy(config);
    }
}

ObjenesisCglibAopProxy

通过自动配置可知proxyTargetClass为true,即使用CGLIB代理——ObjenesisCglibAopProxy
ObjenesisCglibAopProxygetProxy方法继承自父类CglibAopProxy,核心代码如下:

public Object getProxy(@Nullable ClassLoader classLoader) {
    if (logger.isTraceEnabled()) {
        logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
    }

    try {
        // 目标对象类型必须有效,CGLIB是基于类进行代理
        Class<?> rootClass = this.advised.getTargetClass();
        Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

        Class<?> proxySuperClass = rootClass;
        if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
            // 目标对象类型是CGLIB创建的类型
            proxySuperClass = rootClass.getSuperclass();
            Class<?>[] additionalInterfaces = rootClass.getInterfaces();
            for (Class<?> additionalInterface : additionalInterfaces) {
                this.advised.addInterface(additionalInterface);
            }
        }

        // 校验目标类型的final方法
        validateClassIfNecessary(proxySuperClass, classLoader);

        Enhancer enhancer = createEnhancer();
        if (classLoader != null) {
            enhancer.setClassLoader(classLoader);
            if (classLoader instanceof SmartClassLoader &&
                    ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
                enhancer.setUseCache(false);
            }
        }
        // 设置继承的类
        enhancer.setSuperclass(proxySuperClass);
        // 设置需要实现的接口
        enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
        enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
        enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));

        // 获取方法回调
        Callback[] callbacks = getCallbacks(rootClass);
        Class<?>[] types = new Class<?>[callbacks.length];
        for (int x = 0; x < types.length; x++) {
            types[x] = callbacks[x].getClass();
        }
        // ProxyCallbackFilter决定method通过哪一个Callback回调
        enhancer.setCallbackFilter(new ProxyCallbackFilter(
                this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
        enhancer.setCallbackTypes(types);

        // 根据方法回调创建代理类并创建代理类的实例
        return createProxyClassAndInstance(enhancer, callbacks);
    }
    catch (CodeGenerationException | IllegalArgumentException ex) {
        throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
                ": Common causes of this problem include using a final class or a non-visible class",
                ex);
    }
    catch (Throwable ex) {
        // TargetSource.getTarget() failed
        throw new AopConfigException("Unexpected AOP exception", ex);
    }
}

protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
    enhancer.setInterceptDuringConstruction(false);
    enhancer.setCallbacks(callbacks);
    // 有构造参数则使用
    return (this.constructorArgs != null && this.constructorArgTypes != null ?
            enhancer.create(this.constructorArgTypes, this.constructorArgs) :
            enhancer.create());
}

private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
    // Parameters used for optimization choices...
    boolean exposeProxy = this.advised.isExposeProxy();
    boolean isFrozen = this.advised.isFrozen();
    boolean isStatic = this.advised.getTargetSource().isStatic();

    // 用于处理有Advice chain的方法的调用
    Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

    // 用于处理没有Advice chain且可以返回this的方法的调用
    Callback targetInterceptor;
    if (exposeProxy) {
        targetInterceptor = (isStatic ?
                new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
                new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
    }
    else {
        targetInterceptor = (isStatic ?
                new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
                new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
    }

    // 用于处理没有Advice chain且不可以返回this的方法的调用
    Callback targetDispatcher = (isStatic ?
            new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());

    Callback[] mainCallbacks = new Callback[] {
            aopInterceptor,  // for normal advice
            targetInterceptor,  // invoke target without considering advice, if optimized
            new SerializableNoOp(),  // no override for methods mapped to this
            targetDispatcher, this.advisedDispatcher,
            // 处理equals方法调用
            new EqualsInterceptor(this.advised),
            // 处理hashCode方法调用
            new HashCodeInterceptor(this.advised)
    };

    Callback[] callbacks;

    // 如果目标对象是静态的,且Advice chain不支持变动,则可以对方法调用做出优化
    if (isStatic && isFrozen) {
        Method[] methods = rootClass.getMethods();
        Callback[] fixedCallbacks = new Callback[methods.length];
        this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length);

        // 使用FixedChainStaticTargetInterceptor处理方法的调用
        for (int x = 0; x < methods.length; x++) {
            Method method = methods[x];
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
            fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
                    chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
            this.fixedInterceptorMap.put(method, x);
        }

        callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
        System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
        System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
        // 记录FixedChainStaticTargetInterceptor起始位置
        this.fixedInterceptorOffset = mainCallbacks.length;
    }
    else {
        callbacks = mainCallbacks;
    }
    return callbacks;
}

JdkDynamicAopProxy

如果使用JDK动态代理,即JdkDynamicAopProxy,其核心代码如下:

public Object getProxy(@Nullable ClassLoader classLoader) {
    if (logger.isTraceEnabled()) {
        logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
    }
    // 通过Proxy创建代理,将自身作为InvocationHandler传入
    return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}

至此,代理创建的分析就结束了;

代理方法执行

ObjenesisCglibAopProxy

通过自动配置可知,使用的是CGLIB代理,即ObjenesisCglibAopProxy,代理方法的执行是通过Enhancer的Callback机制实现的,在创建CGLIB代理时,会准备代理方法的Callback,然后设置到Enhancer中,代码如下:

protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
    enhancer.setInterceptDuringConstruction(false);
    enhancer.setCallbacks(callbacks);
    // 有构造参数则使用
    return (this.constructorArgs != null && this.constructorArgTypes != null ?
            enhancer.create(this.constructorArgTypes, this.constructorArgs) :
            enhancer.create());
}

JdkDynamicAopProxy

如果使用JDK动态代理,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;
    Object target = null;

    try {
        if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
            // 没有实现equals方法
            return equals(args[0]);
        }
        else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
            // 没有实现hashCode方法
            return hashCode();
        }
        else if (method.getDeclaringClass() == DecoratingProxy.class) {
            // DecoratingProxy只定义了getDecoratedClass方法
            return AopProxyUtils.ultimateTargetClass(this.advised);
        }
        else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
                method.getDeclaringClass().isAssignableFrom(Advised.class)) {
            // Service invocations on ProxyConfig with the proxy config...
            // 代理可以转换为Advised,通过反射执行方法
            return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
        }

        Object retVal;

        if (this.advised.exposeProxy) {
            // 暴露当前代理
            oldProxy = AopContext.setCurrentProxy(proxy);
            setProxyContext = true;
        }

        target = targetSource.getTarget();
        Class<?> targetClass = (target != null ? target.getClass() : null);

        // 获取拦截器链
        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.
        if (chain.isEmpty()) {
            // 没有配置拦截器,则通过反射,直接使用目标对象执行方法
            Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
            retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
        }
        else {
            // We need to create a method invocation...
            // 使用配置的拦截器链创建MethodInvocation
            MethodInvocation invocation =
                    new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
            // MethodInvocation执行时,会先执行完拦截器的逻辑,最后才使用目标对象执行方法
            retVal = invocation.proceed();
        }

        // 处理方法的返回值
        Class<?> returnType = method.getReturnType();
        if (retVal != null && retVal == target &&
                returnType != Object.class && returnType.isInstance(proxy) &&
                !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
            // 如果方法返回值为自身,则修正为代理
            // 但无法做到当返回值持有自身的一个引用时,将引用修正为代理
            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()) {
            // 释放目标对象
            targetSource.releaseTarget(target);
        }
        if (setProxyContext) {
            // 恢复当前上下文的代理
            AopContext.setCurrentProxy(oldProxy);
        }
    }
}

至此,代理方法执行的分析就结束了。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-06 12:48:23  更:2022-03-06 12:49:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:44:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码