• 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

     
     
  • 相关阅读:
    事务四大特征:原子性,一致性,隔离性和持久性(ACID)
    解决“要登录到这台远程计算机,你必须被授予”
    SqlServer_查看SQLServer版本信息
    sed 查找文件的某一行内容
    linux echo命令的-n、-e两个参数
    在.Net中进行跨线程的控件操作(上篇:Control.Invoke)
    .NET性能优化方面的总结
    SQLSERVER2008 显示列信息,包含扩展属性
    C#4.0新特性:可选参数,命名参数,Dynamic
    浅谈.net中的params关键字
  • 原文地址:https://www.cnblogs.com/chenxingyang/p/15559348.html
Copyright © 2020-2023  润新知