在看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创建的。

       

        

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐