ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring 使用 AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry); 注册代理

2020-12-21 19:03:15  阅读:163  来源: 互联网

标签:return registerAutoProxyCreatorIfNecessary Spring beanFactory public AopConfigUt


原先有问题的代码

自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(RateLimiterImportBeanDefinitionRegistrar.class)
public @interface EnableRateLimiter {
    /**
     * 扫描路径
     * @return
     */
    boolean proxyTargetClass() default false;
}
注册APC(AutoProxyCreate)
@Configuration
public class RateLimiterImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(EnableRateLimiter.class.getName());
        Boolean flag = (Boolean) annotationAttributes.get("proxyTargetClass");

        //依赖于Spring底层实现,通常是Spring 内部使用
        AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
        if (flag) {
            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
        }
        GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
        genericBeanDefinition.setBeanClass(RateLimiterConfiguration.class);
        registry.registerBeanDefinition("rateLimiterConfiguration",genericBeanDefinition);
    }
}
注册Advisor
@Configuration//(proxyBeanMethods = false)
public class RateLimiterConfiguration {

    /**
     * 把寻找到的Advice和Pointcut(matches)相互关联(交给StaticMethodMatcherPointcutAdvisor相互关联)
     * @return
     */
    @Bean
    public RateLimiterAdvisor registerRateLimiterAdvisor(RateLimitMethodInterceptor registerMethodInterceptor){
        RateLimiterAdvisor rateLimiterAdvisor = new RateLimiterAdvisor(registerMethodInterceptor);
        return rateLimiterAdvisor;

    }

    /**
     * 寻找Advice
     * @return
     */
    @Bean
    public RateLimitMethodInterceptor registerMethodInterceptor(){
        RateLimitMethodInterceptor rateLimitMethodInterceptor = new RateLimitMethodInterceptor();
        return rateLimitMethodInterceptor;
    }


    //把寻找到的Advice和Pointcut(matches)相互关联(交给StaticMethodMatcherPointcutAdvisor相互关联)
class RateLimiterAdvisor extends StaticMethodMatcherPointcutAdvisor {

    /**
     * 注册Advice
     * @param rateLimitMethodInterceptor
     */
    public RateLimiterAdvisor(RateLimitMethodInterceptor rateLimitMethodInterceptor){
        this.setAdvice(rateLimitMethodInterceptor);
    }

    /**
     * 检索项目中的LocalRateLimiter注解
     * @param method
     * @param targetClass
     * @return
     */
    @Override
    public boolean matches(Method method, Class<?> targetClass) {
        return method.isAnnotationPresent(LocalRateLimiter.class);
    }

}
//获得Advice
class RateLimitMethodInterceptor implements MethodInterceptor {


    @Nullable
    @Override
    public Object invoke(@Nonnull MethodInvocation invocation) throws Throwable {

        Object proceed = invocation.proceed();
        boolean annotationPresent = invocation.getMethod().isAnnotationPresent(LocalRateLimiter.class);
        if (annotationPresent){
            System.out.println("做限流功能!!!!");
            return invocation.getMethod().invoke(invocation.getThis(), invocation.getArguments());
        }
        return proceed;
    }
}
}

最后的结果就是怎么都不进RateLimitMethodInterceptor.invock()方法

通过阅读源码(AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);)了解到:

	@Nullable
	public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
		return registerAutoProxyCreatorIfNecessary(registry, null);
	}

	@Nullable
	public static BeanDefinition registerAutoProxyCreatorIfNecessary(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
	}
public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {

	@Nullable
	private ConfigurableListableBeanFactory beanFactory;


	@Override
	protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		super.initBeanFactory(beanFactory);
		this.beanFactory = beanFactory;
	}

    
	@Override
	protected boolean isEligibleAdvisorBean(String beanName) {
    //通过this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE)可以了解到,如果当前注册的beanDefinition的Role != 2的时候是会返回false的(否认为早期的AdvisorBean在代理的时候不会进行代理。。。。可以看下面的代码)
		return (this.beanFactory != null && this.beanFactory.containsBeanDefinition(beanName) &&
				this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
	}

}
	/** 找到所有候选需要使用自动代理的。在上一步表示为false那么在这一步就不会对Advisor进行代理
	 * Find all candidate Advisors to use in auto-proxying.
	 * @return the List of candidate Advisors
	 */
	protected List<Advisor> findCandidateAdvisors() {
		Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
		return this.advisorRetrievalHelper.findAdvisorBeans();
	}

通过上面的阅读源码了解到 需要对注册的Bean进行Role设置为BeanDefinition.ROLE_INFRASTRUCTURE

解决方案在注册Advisor的时候为Bean添加@Role(BeanDefinition.ROLE_INFRASTRUCTURE)即可

@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class RateLimiterConfiguration {

    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public RateLimiterAdvisor registerRateLimiterAdvisor(RateLimitMethodInterceptor registerMethodInterceptor){
        RateLimiterAdvisor rateLimiterAdvisor = new RateLimiterAdvisor(registerMethodInterceptor);
        return rateLimiterAdvisor;

    }


    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public RateLimitMethodInterceptor registerMethodInterceptor(){
        RateLimitMethodInterceptor rateLimitMethodInterceptor = new RateLimitMethodInterceptor();
        return rateLimitMethodInterceptor;
    }

}

 

标签:return,registerAutoProxyCreatorIfNecessary,Spring,beanFactory,public,AopConfigUt
来源: https://blog.csdn.net/qq_40694145/article/details/111482012

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有