最近业务部门向我们反馈一个问题,我们部门原先提供的组件突然用不了了。后面排查是因为我们提供出去的组件类没有注入到spring 容器中,之前没问题是因为业务部门的根包名跟我们组件的根包名是一样,后续他们根包名换了,导致我们的组件类没法注入到spring中,当时的解决方案是形如下
@SpringBootApplication(scanBasePackages = {"业务根包","组件根包"})
就是在业务的启动类上加上扫描组件根包。
虽然这样的方式可以解决,但是事后复盘了一下,业务方是否需要了解组件根包?是否还有更优雅一点的方式?本文就来聊聊如何把第三方服务注册到我们项目的spring容器中
1、自动装配机制 + @Bean的形式
示例:
@Configuration @Slf4j @EnableConfigurationProperties(XxlJobProperty.class) public class XxlJobAutoConfiguration { @Bean @ConditionalOnMissingBean public XxlJobSpringExecutor xxlJobExecutor(XxlJobProperty property) { log.info(">>>>>>>>>>> xxl-job config init."); XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor(); xxlJobSpringExecutor.setAdminAddresses(property.getAdminAddresses()); xxlJobSpringExecutor.setAppname(property.getExecutorAppname()); xxlJobSpringExecutor.setAddress(property.getExecutorAddress()); xxlJobSpringExecutor.setIp(property.getExecutorIp()); xxlJobSpringExecutor.setPort(property.getExecutorPort()); xxlJobSpringExecutor.setAccessToken(property.getAccessToken()); xxlJobSpringExecutor.setLogPath(property.getExecutorLogPath()); xxlJobSpringExecutor.setLogRetentionDays(property.getExecutorLogRetentionDays()); return xxlJobSpringExecutor; }
在META-INF/spring.factories加入
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.github.lybgeek.autoconfiure.XxlJobAutoConfiguration
2、利用@Eanblexxx + @Import机制
示例:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(HelloSeviceImpl.class) public @interface EnableHelloSvc{ }
在业务项目启动加上@EnableHelloSvc
3、调用beanFactory.registerSingleton()
示例:
@Slf4j public class HelloSvcBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { String beanName = StringUtils.uncapitalize(HelloService.class.getSimpleName()); log.info("register bean : beanName:{}",beanName); beanFactory.registerSingleton(beanName,new HelloServiceImpl()); } }
1、自动装配机制 + @ComponentScan
示例:
@Configuration @ComponentScan(basePackages = Constant.SVC_PACAKAEE) public class ThirdPartySvcAutoConfiguration { }
在META-INF/spring.factories加入
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.github.lybgeek.autoconfiure.ThirdPartySvcAutoConfiguration
2、@Eanblexxx + @Import机制+ClassPathScanningCandidateComponentProvider
示例:
public class ThirdPartySvcRegister implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { ClassPathBeanDefinitionScanner classPathBeanDefinitionScanner = new ClassPathBeanDefinitionScanner(registry); classPathBeanDefinitionScanner.scan(Constant.SVC_PACAKAEE); } }
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(ThirdPartySvcRegister.class) public @interface EnableThirdPartySvc { }
在业务项目启动加上@EnableThirdPartySvc
如果是业务开发人员直接使用
@SpringBootApplication(scanBasePackages = {"业务根包","组件根包"})
其实是没问题的,但是如果作为组件提供给其他业务部门使用,能让业务部门无感知,开箱即用会是比较优雅的方式
https://github.com/lyb-geek/springboot-learning/tree/master/springboot-scan-thirdparty-service