我目前正在为 Retrofit 2 编写 Spring Boot
自动配置。我想做的是编写某种接口(interface)构建器,它能够实例化一个带有一些 Autowiring 注释的接口(interface),就像 Spring Data 对存储库所做的那样。由于我找不到任何关于如何做到这一点的资源(或者是否可以使用 Spring 来完成),我想询问您对此的想法。下面是我想要实例化的接口(interface)。
我对 @Repository
的替换是 @Retrofit
其余的只是您为任何 Retrofit 存储库编写的“普通”代码。
我想要 Autowiring 的接口(interface)类型:
@Retrofit
public interface Api {
@GET("usernames")
String[] getUsernames();
}
Autowiring 的示例:
@SpringBootApplication
public class TestApplication {
@Autowired
private Api api;
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
@Bean
CommandLineRunner runner() {
return args -> {
System.out.println(api.getUsernames());
};
}
}
最佳答案
正如我所说,我找到了解决问题的方法。
首先,我们需要一个由 Spring Boot
加载的自动配置类 - 如所述 here - 添加文件 META-INF/spring.factories
,内容如下所示。此自动配置加载一个注册器,该注册器本身通过组件提供程序搜索带有 @Retrofit
注释的类。最后,注册器为每个可以找到的实例创建 RetrofitFactoryBean
实例,同时该工厂 bean 创建 Retrofit 代理本身。
自动配置
@Configuration
@Import(RetrofitRegistrar.class)
public class RetrofitAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public Retrofit retrofit() {
return new Retrofit.Builder().build();
}
}
META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
spring.retrofit.RetrofitAutoConfiguration
导入的注册商
public class RetrofitRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware {
@Setter
private BeanFactory beanFactory;
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
List<String> basePackages = AutoConfigurationPackages.get(this.beanFactory);
RetrofitComponentProvider provider = new RetrofitComponentProvider(registry);
basePackages.stream()
.map(provider::findCandidateComponents)
.flatMap(Set::stream)
.forEach(comp -> register(comp, registry));
}
private void register(BeanDefinition component, BeanDefinitionRegistry registry) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.
rootBeanDefinition(RetrofitFactoryBean.class);
builder.addConstructorArgValue(component.getBeanClassName());
registry.registerBeanDefinition(
component.getBeanClassName().toLowerCase(), builder.getBeanDefinition());
}
}
组件提供商
class RetrofitComponentProvider extends ClassPathScanningCandidateComponentProvider {
@Getter
private BeanDefinitionRegistry registry;
public RetrofitComponentProvider(BeanDefinitionRegistry registry) {
super(false);
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
this.registry = registry;
addIncludeFilter(new AnnotationTypeFilter(Retrofit.class, true, true));
}
@Override
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
return true;
}
}
工厂 bean
@Component
@RequiredArgsConstructor
public class RetrofitFactoryBean extends AbstractFactoryBean<Object> {
@Getter
private final Class<?> objectType;
private final retrofit2.Retrofit retrofit;
@Override
protected Object createInstance() throws Exception {
return retrofit.create(objectType);
}
}
@Getter
、@Setter
和 @RequiredArgsConstructor
注释由 ProjectLombok 提供。
关于java - Spring 中的改造自动配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45774870/