第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定

聊聊自定義實(shí)現(xiàn)的SPI如何與spring進(jìn)行整合

標(biāo)簽:
Java Spring

前言

上一篇文章主要[聊聊如何实现一个带有拦截器功能的SPI]。今天就来聊聊自定义的SPI如何与spring整合。

思考:我们实现的SPI要整合spring哪些东西?或者我们要利用spring的哪些特性实现我们哪些东西?

spring除了被大家熟知的IOC和AOP之外,还有它也提供了很丰富的扩展点,比如各种后置处理器,今天我们就聊聊大家相对熟悉的话题,如何通过自定义注解把SPI注入到spring容器中

整合思路

1、自定义注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Activate {

    String value() default "";
}

2、自定义bean定义扫描器

public class ActivateClassPathBeanDefinitionScanner extends ClassPathBeanDefinitionScanner {


    public ActivateClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
        super(registry);
    }


    @SneakyThrows
    @Override
    protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {
        super.registerBeanDefinition(definitionHolder, registry);
        Class clz = Class.forName(definitionHolder.getBeanDefinition().getBeanClassName());
        Activate activate = AnnotationUtils.findAnnotation(clz,Activate.class);
        if(ObjectUtils.isNotEmpty(activate) && StringUtils.isNotBlank(activate.value())){
            String activateName = getEnvironment().resolvePlaceholders(activate.value());
            registry.registerBeanDefinition(activateName,definitionHolder.getBeanDefinition());
        }
    }

    @Override
    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
        return super.isCandidateComponent(beanDefinition) && beanDefinition.getMetadata()
                .hasAnnotation(Activate.class.getName());
    }

3、定义ImportBeanDefinitionRegistrar

public class SpiRegister implements ImportBeanDefinitionRegistrar, EnvironmentAware {

    private Environment environment;


    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        Set<String> basePackages = this.getBasePackages(importingClassMetadata);
        String[] packages = {};
        SpiBeanUtils.registerActivateInstances(registry,environment,basePackages.toArray(packages));
    }

4、自定义enabled注解

@Target(value = ElementType.TYPE)
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
@Import(SpiRegister.class)
public @interface EnableSpi {

  
    String[] value() default {};

 
    String[] basePackages() default {};

  
    Class<?>[] basePackageClasses() default {};
}

示例演示

1、在需要注入到spring容器的类上加上@Activate注解

@Activate("hello-mysql")
public class SpringMysqlDialect implements SpringSqlDialect {

    @Autowired
    private MysqlDialectService mysqlDialectService;

    @Override
    public String dialect() {
        return mysqlDialectService.dialect();
    }


}

2、启动类上加上扫描SPI范围注解

@SpringBootApplication(scanBasePackages = "com.github.lybgeek")
@EnableSpi(basePackages = "com.github.lybgeek")
public class SpiTestApplication implements ApplicationRunner 

3、利用getBeansOfType进行验证

 applicationContext.getBeansOfType(SpringSqlDialect.class)
                .forEach((beanName,bean) -> System.out.println(beanName + "-->" + bean));

打印结果如下

hello-mysql-->com.github.lybgeek.dialect.mysql.SpringMysqlDialect@433348bc

说明已经注入到spring容器中

总结

把项目的服务托管给spring ioc容器,可以算是与spring整合比较基础的动作,本文演示也是相对基础的一环,spring 强大的地方,在于它的扩展性,在spring bean的生命周期中,基本上随处可见扩展点,感兴趣的朋友后续可以自行体会验证

demo链接

點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺(jué)得本文不錯(cuò),就分享一下吧!

評(píng)論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評(píng)論
  • 收藏
  • 共同學(xué)習(xí),寫下你的評(píng)論
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說(shuō)多少就多少
贊賞金額會(huì)直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊(cè)有機(jī)會(huì)得

100積分直接送

付費(fèi)專欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會(huì)
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)

舉報(bào)

0/150
提交
取消