当前位置: 首页 > 后端技术 > Java

使用mybatis-plus的多数据源方案aop不生效问题的排查

时间:2023-04-01 16:07:56 Java

使用mybatis-plus的多数据源解决aop解决不生效问题是aop不生效com.baomidoumybatis-plus-boot-starter3.3.0com.baomidoudynamic-datasource-spring-boot-starter3.3.3在DynamicDataSourceAutoConfiguration类中定义了一个bean@Role(value=BeanDefinition.ROLE_INFRASTRUCTURE)@Bean@ConditionalOnMissingBeanpublicAdvisordynamicDatasourceAnnotationAdvisor(DsProcessordsProcessor){DynamicDataSourceAnnotationInterceptor拦截器=newDynamicDataSourceAnnotationInterceptor(properties.isAllowed)处理器);DynamicDataSourceAnnotationAdvisoradvisor=newDynamicDataSourceAnnotationAdvisor(拦截器);advisor.setOrder(properties.getOrder());回归顾问;}这个配置类中定义的其他bean都被初始化了,只有这个bean没有被初始化,而这个类的作用就是定义aop的切面和入口点。如果我在自己的配置类中定义这个bean,我就可以初始化它。经过调试,主要是使用了@ConditionalOnMissingBean注解。不知道为什么dynamic-datasource-spring-boot-starter的作者要在spring加载其他Advisor实现类的时候加上这个注解(我主要是指spring缓存依赖,配置类ProxyCachingConfiguration定义了一个BeanFactoryCacheOperationSourceAdvisor),所以bean不会被加载。为此,跑了一遍spring的@Bean加载过程,分析如下:springboot启动时,有一个实现了ConfigurationClassPostProcessor的回调接口BeanDefinitionRegistryPostProcessor。这个实现类的作用是加载所有的@Configuration会使用ConfigurationClassParser类进行解析,会解析是否有@ComponentScans()、@ComponentScan(@SpringApplication注解中也使用了这个注解)。然后使用ComponentScanAnnotationParser#parse根据basePackage属性进行进一步扫描,然后使用ClassPathBeanDefinitionScanner#doScan,#findCandidateComponents扫描所有spring组件和config(扫描内容由ClassPathBeanDefinitionScanner的filter判断,这里会扫描所有@Component,@Configuation@Component中也用到了,所以会被扫描)然后继续递归解析,最后得到所有的config(并通过ConfigurationClassParser得到config中所有的@Bean信息并保存到BeanMethod属性中#retrieveBeanMethodMetadata)和组件;然后使用ConfigurationClassBeanDefinitionReader#loadBeanDefinitions读取并加载config的bean配置添加到BeanDefinition中。这就是整个BeanDefinition的加载过程。可以看到加载过程是有顺序的。首先会加载当前SpringBootApplication目录下的配置,所以我针对上面的问题写了一个配置。在使用@Bean的时候就可以加载,因为此时还没有加载其他依赖包和配置,所以只有这个Advisor实现类,所以可以加载成功。classpath目录下的其他配置类在加载完成后才会加载。