SpringAOP[6]-按照name的自动代理

2021/11/16 6:09:50

本文主要是介绍SpringAOP[6]-按照name的自动代理,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1. 测试方法

通知类:

public class LogMethodBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("this is logMethodBeforeAdvice!");
    }
}

public class Log2MethodBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("xxxxxxxxxxxxxxxxx");
    }
}

目标接口以及目标类:

public interface IAccount {
    String say(@NotNull Integer id, @NotNull String desc);
    String run();
    //接口内部定义了hashCode方法
    int hashCode();
}
public class AccountImpl implements IAccount {
    @Override
    public String say(@NotNull Integer id, @NotNull String desc) {
        return "my "+id + ":" + desc;
    }

    @Override
    public String run() {
        return "I am runner";
    }

    //继承的是IAccount的hashCode方法
    @Override
    public int hashCode() {
        return 123;
    }
    //继承的是Object的equals方法
    @Override
    public boolean equals(Object obj) {
        return super.equals(obj);
    }
}

测试方法:

@Configuration
public class DefaultAdvisorAutoProxyCreatorConfig {
    //目标类
    @Bean
    public IAccount accountImpl(){
        return new AccountImpl();
    }
    //切面类
    @Bean
    public Log2MethodBeforeAdvice log2(){
        return new Log2MethodBeforeAdvice();
    }
    //声明自动代理器
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        return new DefaultAdvisorAutoProxyCreator();
    }
    //声明Advisor
    @Bean
    public NameMatchMethodPointcutAdvisor nameMatchMethodPointcutAdvisor() {
        NameMatchMethodPointcutAdvisor nameAdvisor = new NameMatchMethodPointcutAdvisor();
        //拦截方法
        nameAdvisor.addMethodName("*say");
        nameAdvisor.setAdvice(new LogMethodBeforeAdvice());
        return nameAdvisor;
    }
}

 

 

2. 类结构

 

DefaultAdvisorAutoProxyCreatorAbstractAdvisorAutoProxyCreator的子类,由下面方法可知,实现了isEligibleAdvisorBean方法。

 

AbstractAdvisorAutoProxyCreator类是AbstractAutoProxyCreator的子类,由下面方法可知,实现了getAdvicesAndAdvisorsForBean()advisorsPreFiltered()方法。

  • getAdvicesAndAdvisorsForBean()方法:获取该bean对象上所有的Advisor对象(实现自动代理的核心方法);
  • advisorsPreFiltered():默认返回true,是着ProxyFactory代理配置;

AbstractAutoProxyCreator是模板类,即Spring完成自动代理的模板方法,定义了算法骨干。子类实现其定义的钩子方法,完成bean的自动代理。

 

3. 源码分析

3.1 Spring的自动加载流程

调用如下方法:getBean()获取单例池中的bean对象。而bean被初始化时,就会被自动代理。

public class TestSpringProxy {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(DefaultAdvisorAutoProxyCreatorConfig.class);
        //可以使用@Primary指定元素,或直接使用name名获取。
        IAccount bean = (IAccount)applicationContext.getBean("accountImpl");
        bean.say(100,"工作");
        System.out.println(bean.getClass());
    }
}

 

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
        implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
    //前置处理,未进行代理
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean;
    }
}

 

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
        implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
    @Override
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            //获取cacheKey的(对FactoryBean进行处理,加入了&)
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            //判断是否被循环依赖时早期加载
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
               //包装Bean对象(自动代理)
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }
}

 

 

3.2 创建代理对象

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
        implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
    private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
    private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256);

    //包装bean对象
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        //若bean已经在targetSourcedBeans集合中,说明已经被代理过,直接返回即可。
        //`postProcessBeforeInstantiation()`中成功创建的代理对象会将beanName加入到`targetSourceBeans`中。
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        //若该Bean是基础框架或者免代理的Bean,也不进行处理。
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        //若`Pointcut`、`Advice`、`Advisor`、`AopInfrastructureBean`也不会进行代理,并且加入到advisedBeans集合中。
       //或者判断是否跳过(shouldSkip也是一个钩子方法)
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }

        // (重要方法)获取bean上的advice和advisor对象。(该方法是`AbstractAdvisorAutoProxyCreato`内的方法)。获取合格的Advisor
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }

        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }
}

AbstractAutoProxyCreator#shouldSkip的方法,也是一个钩子方法。AspectJAwareAdvisorAutoProxyCreator(子类)实现了shouldSkip方法。

父类中shouldSkip方法作用是判断该bean是否是beanName.ORIGINAL的类型,若bean是这种类型,则跳过。

 

获取bean上的advice和advisor对象。

 

public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
    @Nullable
    private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper;

    @Override
    @Nullable
    protected Object[] getAdvicesAndAdvisorsForBean(
            Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
        //获取`合格`的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) {    
        //获取候选的Advisor集合对象;
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        //筛选候选的Advisor对象,获取`合格的Advisor`对象集合;
        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        //子类实现(扩展Advisors)
        extendAdvisors(eligibleAdvisors);
        //Advisor按照Order接口进行排序。
        if (!eligibleAdvisors.isEmpty()) {
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        //返回该bean上的Advicor对象
        return eligibleAdvisors;
    }
    //获取`所有候选的Advisor集合`(钩子方法,子类也会实现)
    protected List<Advisor> findCandidateAdvisors() {
        Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
        return this.advisorRetrievalHelper.findAdvisorBeans();
    }
    //获取`合格的Advisor`集合
    protected List<Advisor> findAdvisorsThatCanApply(
            List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

        ProxyCreationContext.setCurrentProxiedBeanName(beanName);
        try {
            return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
        }
        finally {
            ProxyCreationContext.setCurrentProxiedBeanName(null);
        }
    }
    //钩子方法,未实现。
    protected void extendAdvisors(List<Advisor> candidateAdvisors) {
    }
    //适配器模式(主要为了实现isEligibleAdvisorBean方法)
    private class BeanFactoryAdvisorRetrievalHelperAdapter extends BeanFactoryAdvisorRetrievalHelper {

        public BeanFactoryAdvisorRetrievalHelperAdapter(ConfigurableListableBeanFactory beanFactory) {
            super(beanFactory);
        }
        //获取合格的Bean的对象。
        @Override
        protected boolean isEligibleBean(String beanName) {
            return AbstractAdvisorAutoProxyCreator.this.isEligibleAdvisorBean(beanName);
        }
    }

}

获取Spring中所有的Advisor

public class BeanFactoryAdvisorRetrievalHelper {
    //维护的Advisor缓存(初始时为null)
    @Nullable
    private volatile String[] cachedAdvisorBeanNames;

    public List<Advisor> findAdvisorBeans() {
        String[] advisorNames = this.cachedAdvisorBeanNames;
        //初始化时为null
        if (advisorNames == null) {
            //从容器中(包含父容器)中获取Advisor类型的Bean对象的名字。【注意是Advisor类型,而非Advice类型】
            advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                    this.beanFactory, Advisor.class, true, false);
            //放入本地缓存中。
            this.cachedAdvisorBeanNames = advisorNames;
        }
        if (advisorNames.length == 0) {
            return new ArrayList<>();
        }

        List<Advisor> advisors = new ArrayList<>();
        //获取Spring容器中所有的advisors后开始处理。
        for (String name : advisorNames) {
            //判断该Advisor是否是可以自动代理的Advisor(由子类实现判断)
            if (isEligibleBean(name)) {
                //若bean正在创建,那么什么都不做。
                if (this.beanFactory.isCurrentlyInCreation(name)) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Skipping currently created advisor '" + name + "'");
                    }
                }
                //bean已经被创建后
                else {
                    try {
                        //创建Bean,放入List<Advisor>中。
                        advisors.add(this.beanFactory.getBean(name, Advisor.class));
                    }
                    catch (BeanCreationException ex) {
                        ...
                        continue;
                        }
                        throw ex;
                    }
                }
            }
        }
        return advisors;
    }
    //钩子方法(由具体子类实现)
    protected boolean isEligibleBean(String beanName) {
        return true;
    }
}

 

子类的特殊实现:
public class DefaultAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator implements BeanNameAware {
    private boolean usePrefix = false;
    @Nullable
    private String advisorBeanNamePrefix;
    @Override
    protected boolean isEligibleAdvisorBean(String beanName) {
        //usePrefix boolean类型,默认false
        if (!isUsePrefix()) {
            return true;
        }
        String prefix = getAdvisorBeanNamePrefix();
        return (prefix != null && beanName.startsWith(prefix));
    }
}

获取bean上的Advisor

public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
    //遭到Bean上合格的Advisor
    protected List<Advisor> findAdvisorsThatCanApply(
            List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
      //将beanName放入到`currentProxiedBeanName`中,以便可以在ThreadLocal中获取。
        ProxyCreationContext.setCurrentProxiedBeanName(beanName);
        try {
            //candidateAdvisors:Spring容器中所有的advisor对象;
            //beanClass:Bean对象类型;
            return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
        }
        finally {
            ProxyCreationContext.setCurrentProxiedBeanName(null);
        }
    }
}

AopUtils的工具方法:\

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {  
    //若是传入的容器内Advisor为空,直接返回
    if (candidateAdvisors.isEmpty()) {  
        return candidateAdvisors;  
    }  
    List<Advisor> eligibleAdvisors = new ArrayList<>();  
    //bean匹配`引介通知`。
    for (Advisor candidate : candidateAdvisors) {  
        //判断是否是引介通知(引介通知只有ClassFilter),且匹配
        if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {  
            eligibleAdvisors.add(candidate);  
        }  
    }  
    //判断是否存在`合格的引介通知`
    boolean hasIntroductions = !eligibleAdvisors.isEmpty();  
    //匹配普通通知
    for (Advisor candidate : candidateAdvisors) {  
        if (candidate instanceof IntroductionAdvisor) {  
            continue;  
        }  
        //查看是否匹配(普通通知)
        if (canApply(candidate, clazz, hasIntroductions)) {  
            eligibleAdvisors.add(candidate);  
        }  
    }  
    return eligibleAdvisors;  
}  
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;  
        return canApply(pca.getPointcut(), targetClass, hasIntroductions);  
    }  
    else {  
        // It doesn't have a pointcut so we assume it applies.  
        return true;  
    }  
}  
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {  
    Assert.notNull(pc, "Pointcut must not be null");  
    //切点的classFilter是否匹配
    if (!pc.getClassFilter().matches(targetClass)) {  
        return false;  
    }  
    //获取切点的methodMatcher
    MethodMatcher methodMatcher = pc.getMethodMatcher();  
    //若是方法匹配的值为MethodMatcher.TRUE,则拦截所有的方法
    if (methodMatcher == MethodMatcher.TRUE) {  
        return true;  
    }  
  
    IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;  
    if (methodMatcher instanceof IntroductionAwareMethodMatcher) {  
        introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;  
    }  
  
    Set<Class<?>> classes = new LinkedHashSet<>();  
    //若不是JDK代理
    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) {  
            //所有的方法进行匹配(包含私有方法),若有一个匹配,那么返回true。
            if (introductionAwareMethodMatcher != null ?  
                    introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :  
                    methodMatcher.matches(method, targetClass)) {  
                return true;  
            }  
        }  
    }  
  
    return false;  
}  

 

 

创建代理对象

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
        implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

    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;
        }
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }

        //此时我们在这(获取到该Bean上的所有Advisor对象)
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        if (specificInterceptors != DO_NOT_PROXY) {
            //将该Bean放入到advisedBeans集合中。
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            //在SingletonTargetSource获取targetSource。
            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;
    }
    //创建代理对象
    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获取Proxy对象。
        ProxyFactory proxyFactory = new ProxyFactory();
        //复制ProxyConfig配置属性。
        proxyFactory.copyFrom(this);
        //若proxyTargetClass=false,则为JDK代理;
        //若proxyTargetClass=true,则为CGLIB代理
        if (!proxyFactory.isProxyTargetClass()) {
            //判断是否应该使用targetClass类而不是接口进行代理。
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
               //把这个类实现的接口们,放入到ProxyFactory中。
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
        //处理Advisor对象
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        proxyFactory.addAdvisors(advisors);
        proxyFactory.setTargetSource(targetSource);
        //子类定制proxyFactory对象
        customizeProxyFactory(proxyFactory);

        proxyFactory.setFrozen(this.freezeProxy);
       //  注意此处。
        if (advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }
        //创建代理对象。
        return proxyFactory.getProxy(getProxyClassLoader());
    }

    //specificInterceptors:该Bean上所有的Advisor。
    protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
        Advisor[] commonInterceptors = resolveInterceptorNames();

        List<Object> allInterceptors = new ArrayList<>();
        if (specificInterceptors != null) {
            allInterceptors.addAll(Arrays.asList(specificInterceptors));
            if (commonInterceptors.length > 0) {
                 //绝对拦截器加入的顺序
                if (this.applyCommonInterceptorsFirst) {
                    allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
                }
                else {
                    allInterceptors.addAll(Arrays.asList(commonInterceptors));
                }
            }
        }

        Advisor[] advisors = new Advisor[allInterceptors.size()];
        for (int i = 0; i < allInterceptors.size(); i++) {
            advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
        }
        return advisors;
    }
    //处理拦截器Name,去容器内找出来
    private Advisor[] resolveInterceptorNames() {
        BeanFactory bf = this.beanFactory;
        ConfigurableBeanFactory cbf = (bf instanceof ConfigurableBeanFactory ? (ConfigurableBeanFactory) bf : null);
        List<Advisor> advisors = new ArrayList<>();
        for (String beanName : this.interceptorNames) {
            //若工厂不是ConfigurableBeanFactory 或者该Bean不在创建中
            if (cbf == null || !cbf.isCurrentlyInCreation(beanName)) {
                Assert.state(bf != null, "BeanFactory required for resolving interceptor names");
                //拿到这个Bean,将其包装为Advisor。
                Object next = bf.getBean(beanName);
                advisors.add(this.advisorAdapterRegistry.wrap(next));
            }
        }
        return advisors.toArray(new Advisor[0]);
    }

}

 

上述的buildAdvisors()方法中存在resolveInterceptorNames()方法,实际上是处理数组interceptorNames中的beanName,将其在Spring单例池中获取到,并且加入到advisors中。

当然需要依赖applyCommonInterceptorsFirst参数的值来决定拦截器的顺序。

需要注意的是:是否创建代理对象由pointcut来决定。而创建出代理对象执行方法时,该方法会选择合适和Advisor进行织入。而Bean会保存所有相关的Advisor

 

 

执行代理方法

为每个方法生成过滤链:依旧依赖的是pointcutClassFilterMethodMatcher对Advice的过滤。

依赖的是NameMatchMethodPointcut对名字的过滤:

public class NameMatchMethodPointcut extends StaticMethodMatcherPointcut implements Serializable {

    private List<String> mappedNames = new ArrayList<>();
    @Override
    public boolean matches(Method method, Class<?> targetClass) {
       //mappedNames为传入的名字匹配模式
        for (String mappedName : this.mappedNames) {
            //判断是否匹配
            if (mappedName.equals(method.getName()) || isMatch(method.getName(), mappedName)) {
                return true;
            }
        }
        return false;
    }
}

若是符合条件,那么该方法上会生成过滤器链。

为什么AbstractAdvisorAutoProxyCreator要实现这个advisorsPreFiltered()这个方法?

  • 创建代理流程:找到该Bean对象上所有的Advisor时,使用了Advisor中Pointcut的类过滤方法过滤
  • 使用代理对象:需要为每个方法创建AdvisorChain,而Bean对象已经在创建代理流程中使用了类过滤,那么创建AdvisorChain无需在进行类过滤

如上图所示,该属性使用的场景均是获取方法的AdvisorChain时进行ClassFilter过滤的场景。

 

推荐阅读

https://blog.csdn.net/f641385712/article/details/88904983

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

   

 



这篇关于SpringAOP[6]-按照name的自动代理的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程