spring plugin

本文介绍了Spring Plugin的使用,它是一个轻量级的插件框架。通过@EnablePluginRegistries注解和PluginRegistry接口,可以方便地实现插件的注册和管理。示例中展示了如何创建Vehicle接口及其Car和Plane实现,并通过车辆注册表进行插件的调用。源码解析部分详细解释了PluginRegistriesBeanDefinitionRegistrar如何动态注入BeanDefinition。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        在看swagger的源码的时候,发现swagger大量使用了spring-plugin,这个组件在其他地方并不常见,看了其Github:https://github.com/spring-projects/spring-plugin。被称为世界上最小的插件系统,看源码结构,可以看到确实很小,只有那么几个类而已:

         下面用spring plugin写一个例子:

@Configuration
@EnablePluginRegistries({Vehicle.class})
public class SpringPluginTestConfig {

上面是配置类型

public interface Vehicle extends Plugin<Wether> {

    public void reachGoal(Wether wether);
}

Vehicle类是交通工具接口,继承了Plugin接口

public class Car implements Vehicle {


    @Override
    public void reachGoal(Wether wether) {
        supports(wether);
        System.out.println("汽车。。。");
    }

    @Override
    public boolean supports(Wether delimiter) {
        return false;
    }
}

public class Plane implements Vehicle {


    @Override
    public void reachGoal(Wether wether) {

        System.out.println("飞机。。。");
    }

    @Override
    public boolean supports(Wether delimiter) {
        return false;
    }
}

上面两个是定义的具体的交通工具:汽车、飞机。两个类都实现了Vehicle的工具。

 @Autowired
    @Qualifier("vehicleRegistry")
    PluginRegistry<Vehicle, Wether> vehicleRegistry;

    @GetMapping("/checkPlugin")
    public void checkPlugin() {

        List<Vehicle> vehicles = vehicleRegistry.getPlugins();
        Wether wether = new Wether();
        for (Vehicle vehicle : vehicles) {
            vehicle.reachGoal(wether);
        }
    }

通过自动注入vehicleRegistry,调用getPlugins方法就可以获取vehicle列表了。

plugin的源码

源码解析:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Import(PluginRegistriesBeanDefinitionRegistrar.class)
public @interface EnablePluginRegistries {

这个方法import了PluginRegistriesBeanDefinitionRegistrar

public class PluginRegistriesBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

	/* 
	 * (non-Javadoc)
	 * @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar#registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata, org.springframework.beans.factory.support.BeanDefinitionRegistry)
	 */
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

		Class<?>[] types = (Class<?>[]) importingClassMetadata.getAnnotationAttributes(
				EnablePluginRegistries.class.getName()).get("value");  //这里会获取@EnablePluginRegistries注解中的value,这里就是

		for (Class<?> type : types) {

			BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(PluginRegistryFactoryBean.class);
			builder.addPropertyValue("type", type);

			AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
			Qualifier annotation = type.getAnnotation(Qualifier.class);

			// If the plugin interface has a Qualifier annotation, propagate that to the bean definition of the registry
			if (annotation != null) {
				AutowireCandidateQualifier qualifierMetadata = new AutowireCandidateQualifier(Qualifier.class);
				qualifierMetadata.setAttribute(AutowireCandidateQualifier.VALUE_KEY, annotation.value());
				beanDefinition.addQualifier(qualifierMetadata);
			}

			// Default
			String beanName = annotation == null ? StringUtils.uncapitalize(type.getSimpleName() + "Registry") : annotation
					.value();  //这里就是对象的名字,我们的例子里就是vehicle+Registry = vehicleRegistry
			registry.registerBeanDefinition(beanName, builder.getBeanDefinition());
		}
	}
}

通过这个方法,就动态注入了BeanDefinition,进而在后续创建bean的时候使用到。对应的plugin都是PluginRegistryFactoryBean创建的。

       

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值