1

聊聊如何把第三方服务注册到我们项目的spring容器中

 2 years ago
source link: https://segmentfault.com/a/1190000040749186
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

聊聊如何把第三方服务注册到我们项目的spring容器中

最近业务部门向我们反馈一个问题,我们部门原先提供的组件突然用不了了。后面排查是因为我们提供出去的组件类没有注入到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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK