我想为实体的RestRepositoryResource(和一些其他标准功能)实现自动配置。我试图通过在@Configuration
或@SpringBootApplication
注释的类上添加注释来实现它。
类似这样的东西:
@EnableRestRepo(single="foo", collection="foos",entity=Foo.class, id=String.class)
@SpringBootApplication
public class App{
public void main(String[] args){
SpringApplication.run(App.class,args);
}
}
@Entity
public class Foo{
String id;
String bar;
... getters & setters
}
然后应该设置一个(或类似的功能,如果需要,我可以创建自己的端点)@RestRepositoryResource
,
@RestRepositoryResource(itemResourceRel = "foo", collectionResourceRel = "foos")
public interface Repo extends CrudRepository<Foo,String> {
@RestResource(rel = "foo")
Foo findOneById(@Param("id") String id);
}
此处的目标是减少一些用于配置某些基本功能的模板。显然,此示例将使用更多自动配置内容进行扩展,但这应该以类似的方式工作。
问题不仅仅与RestRepositoryResource
有关,而是与带有需要参数和泛型类型类的批注的自动配置有关。我不介意花一些时间来实现这一点,但是我不知道从哪里开始。
像这样甚至有可能吗?如果可以,怎么办?
答案 0 :(得分:4)
不确定我是否100%理解您,但是此处的示例代码运行良好,并基于注释创建了bean运行时。注释也具有som元数据。
通用接口,稍后将进行代理:
public interface GenericRepository<T extends GenericType, Long> extends JpaRepository<GenericType, Long> {
}
放置在不同实体上的注释:
@Target(ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@OverrideAutoConfiguration(enabled = false)
@ImportAutoConfiguration
@Import({RestResourceAutoConfiguration.class})
public @interface EnableRestRepo {
Class<?> entity();
String id();
}
可以在运行时注册bean的配置类:
@Configuration
@AutoConfigureAfter(value = WebMvcAutoConfiguration.class)
@ConditionalOnClass({CrudRepository.class})
public class RestResourceAutoConfiguration implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
Reflections reflections = new Reflections("jav");
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(EnableRestRepo.class);
for (Class<?> c : annotated) {
EnableRestRepo declaredAnnotation = c.getDeclaredAnnotation(EnableRestRepo.class);
Class<?> entity = declaredAnnotation.entity();
String id = declaredAnnotation.id();
Supplier<GenericRepository> genericRepositorySupplier = () -> (GenericRepository) Proxy.newProxyInstance( // register a proxy of the generic type in spring context
c.getClassLoader(),
new Class[]{GenericRepository.class},
new MyInvocationHandler(entity));
beanDefinitionRegistry.registerBeanDefinition(id + "-" + UUID.randomUUID().toString(),
new RootBeanDefinition(GenericRepository.class, genericRepositorySupplier)
);
}
}
META-INF下的spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
jav.RestResourceAutoConfiguration