SpringAOP解析

系列文章目录

切点匹配解析
Advisor与@Aspect解析
getPointcut解析
Advisor解析



前言

SpringAOP是通过调用AnnotationAwareAspectJAutoProxyCreator类创建creator对象从而开始AOP功能,而具体执行的方法则是通过wrapIfNecessary()方法对目标类进行切面创建、代理生成等功能

// 实例化creator
AnnotationAwareAspectJAutoProxyCreator creator = new AnnotationAwareAspectJAutoProxyCreator();
// 初始化bean工厂
creator.initBeanFactory(beanFactory);
// 创建代理过程
Object o1 = creator.wrapIfNecessary(new Target1(), "target1", "target1");
((Target1) o1).foo();

一、模拟AnnotationAwareAspectJAutoProxyCreator

创建模拟的AnnotationAwareAspectJAutoProxyCreator类仍与AnnotationAwareAspectJAutoProxyCreator类一样扩展了AspectJAwareAdvisorAutoProxyCreator类在这里插入图片描述
SimulateAnnotationAwareAspectJAutoProxyCreator类实际是通过initBeanFactory()方法进行初始化传入参数为ConfigurableListableBeanFactory类的beanFactory
initBeanFactory功能:
1.实例化SimulateAbstractAspectJAdvisorFactoryImpl对象作为aspectJAdvisorFactory(模拟AbstractAspectJAdvisorFactory)
2.BeanFactoryAspectJAdvisorsBuilderAdapter封装传入的beanFactory与1中实例化的aspectJAdvisorFactory

public class SimulateAnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
    @Nullable
    private AspectJAdvisorFactory aspectJAdvisorFactory;
    @Nullable
    private SimulateBeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;
    public SimulateAnnotationAwareAspectJAutoProxyCreator() {
    }

    protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        super.initBeanFactory(beanFactory);
        if (this.aspectJAdvisorFactory == null) {
            // this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
            this.aspectJAdvisorFactory = new SimulateAbstractAspectJAdvisorFactoryImpl();
        }
        this.aspectJAdvisorsBuilder = new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
    }
}

BeanFactoryAspectJAdvisorsBuilderAdapter

BeanFactoryAspectJAdvisorsBuilderAdapter方法继承SimulateBeanFactoryAspectJAdvisorsBuilder(该方法也是模拟方法),从构造函数中可以得知其是通过父类的构造方法进行实例化即SimulateBeanFactoryAspectJAdvisorsBuilder()中进行实例化

private class BeanFactoryAspectJAdvisorsBuilderAdapter extends SimulateBeanFactoryAspectJAdvisorsBuilder {
    public BeanFactoryAspectJAdvisorsBuilderAdapter(ListableBeanFactory beanFactory, AspectJAdvisorFactory advisorFactory) {
        super(beanFactory, advisorFactory);
    }

    protected boolean isEligibleBean(String beanName) {
        return SimulateAnnotationAwareAspectJAutoProxyCreator.this.isEligibleAspectBean(beanName);
    }
}

SimulateBeanFactoryAspectJAdvisorsBuilder

SimulateBeanFactoryAspectJAdvisorsBuilder中构造方法即单独封装了beanFactory与advisorFactory两个工厂对象(后续切面获取时会用到)

public class SimulateBeanFactoryAspectJAdvisorsBuilder {
    private ListableBeanFactory beanFactory;
    private AspectJAdvisorFactory advisorFactory;

    public SimulateBeanFactoryAspectJAdvisorsBuilder(ListableBeanFactory beanFactory, AspectJAdvisorFactory advisorFactory) {
        this.beanFactory = beanFactory;
        this.advisorFactory = advisorFactory;
    }
}

initBeanFactory传入spring的beanFactory同时内部实例化advisorFactory,然后将两个工厂通过BeanFactoryAspectJAdvisorsBuilderAdapter进行封装

二、wrapIfNecessary()

wrapIfNecessary核心功能:
1.获取当前bean匹配的切面集合
2.为当前bean创建代理

@Override
public Object wrapIfNecessary(Object bean, String beanName, Object cacheKey){
    // 找到和当前bean匹配的advisor
    Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
    // 创建代理
    Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
    return proxy;
}

切面获取与匹配

根据方法名得知该方法是获取当前bean切面对象
给定当前bean类型与bean名称通过findEligibleAdvisors()获取切面对象集合并返回

@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
    List<Advisor> advisors = this.findEligibleAdvisors(beanClass, beanName);
    return advisors.isEmpty() ? DO_NOT_PROXY : advisors.toArray();
}

findEligibleAdvisors中通过findCandidateAdvisors()方法获取所有候选的advisor对象(解析获取advisor) 然后通过findAdvisorsThatCanApply()方法确定能够匹配当前bean方法的advisor集合并返回

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    // 获取候选Advisors对象(解析advisors实例)
    List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
    // 从所有advisor中,筛选出跟当前bean匹配的advisor
    List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    this.extendAdvisors(eligibleAdvisors);
    if (!eligibleAdvisors.isEmpty()) {
        eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
    }

    return eligibleAdvisors;
}

切面获取:findCandidateAdvisors()

通过aspectJAdvisorsBuilder.buildAspectJAdvisors()方法进行切面集合获取
同时可以发现buildAspectJAdvisors()是调用内部类aspectJAdvisorsBuilder中的方法

// 获取advisor切面对象
protected List<Advisor> findCandidateAdvisors() {
    //找到继承 Advisor 的 advisor
    List<Advisor> advisors = super.findCandidateAdvisors();
    // Build Advisors for all AspectJ aspects in the bean factory.
    if (this.aspectJAdvisorsBuilder != null) {
        //通过解析切面获取 advisor
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    }
    return advisors;
}

即buildAspectJAdvisors是aspectJAdvisorsBuilder内部类中的方法,且因为内部类中封装了beanFactory与advisorFactory对象,在进行切面获取时可以直接调用

public List<Advisor> buildAspectJAdvisors() {
   // 获取所有Object类型 bean名称
    String[] strings1 = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
    List<Advisor> advisors = new ArrayList<>();
    for (String beanName : strings1) {
        Class<?> beanType = this.beanFactory.getType(beanName);
        // 通过advisor工厂验证当前类型是否为@Aspect类型切面
        if (this.advisorFactory.isAspect(beanType)) {
            AspectMetadata aspectMetadata = new AspectMetadata(beanType, beanName);
            // 目前仅考虑单例解析
            // BeanFactoryAspectInstanceFactory是一个MetadataFactory
            BeanFactoryAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
            List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
            if (classAdvisors != null){
                advisors.addAll(classAdvisors);
            }
        }
    }
    return advisors;
}

具体切面获取的解析过程Advisor获取解析


切面匹配:findAdvisorsThatCanApply()

主要通过AopUtils.findAdvisorsThatCanApply()方法进行匹配,具体过程可以查看切面配对解析

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

    List var4;
    try {
        var4 = AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
    } finally {
        ProxyCreationContext.setCurrentProxiedBeanName((String)null);
    }

    return var4;
}

代理创建

代理创建主要通过当前creator中的createProxy()方法进行创建,具体过程可以参考JDK代理创建

@Override
public Object wrapIfNecessary(Object bean, String beanName, Object cacheKey){
    // 找到和当前bean匹配的advisor
    Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
    // 创建代理
    Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
    return proxy;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值