聊聊如何把第三方服務註冊到我們專案的spring容器中

linyb極客之路發表於2021-09-28

前言

最近業務部門向我們反饋一個問題,我們部門原先提供的元件突然用不了了。後面排查是因為我們提供出去的元件類沒有注入到spring 容器中,之前沒問題是因為業務部門的根包名跟我們元件的根包名是一樣,後續他們根包名換了,導致我們的元件類沒法注入到spring中,當時的解決方案是形如下

@SpringBootApplication(scanBasePackages = {"業務根包","元件根包"})

就是在業務的啟動類上加上掃描元件根包。

雖然這樣的方式可以解決,但是事後覆盤了一下,業務方是否需要了解元件根包?是否還有更優雅一點的方式?本文就來聊聊如何把第三方服務註冊到我們專案的spring容器中

注入方式

1、注入的元件個數比較少

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());
    }
}

2、注入的元件個數比較多

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 = {"業務根包","元件根包"})

其實是沒問題的,但是如果作為元件提供給其他業務部門使用,能讓業務部門無感知,開箱即用會是比較優雅的方式

demo連結

https://github.com/lyb-geek/springboot-learning/tree/master/springboot-scan-thirdparty-service

相關文章