如何使用bytebuddy注册自定义JPA接口



我需要注册一个从JpaRepository扩展的自定义接口。我找到了一种使用bytebuddy的方法,如何创建一个从JpaRepository扩展的接口,但我没有找到,如何将他注册为Bean。

AnnotationDescription name = AnnotationDescription.Builder.ofType(Column.class)
.define("name", "type")
.build();
AnnotationDescription id = AnnotationDescription.Builder.ofType(Id.class)
.build();
AnnotationDescription entity = AnnotationDescription.Builder.ofType(Entity.class)
.build();
AnnotationDescription table = AnnotationDescription.Builder.ofType(Table.class)
.define("name", "generated_view")
.build();
Class<?> type = new ByteBuddy()
.subclass(Object.class)
.name("GeneratedModelX")
.annotateType(entity)
.annotateType(table)
.defineField("id", Integer.class, Visibility.PRIVATE)
.annotateField(id)
.defineField("name", String.class, Visibility.PRIVATE)
.annotateField(name)
.defineMethod("getId", Integer.class, Visibility.PUBLIC)
.intercept(FieldAccessor.ofBeanProperty())
.defineMethod("setId", void.class, Visibility.PUBLIC)
.withParameter(Integer.class)
.intercept(FieldAccessor.ofBeanProperty())
.defineMethod("getName", String.class, Visibility.PUBLIC)
.intercept(FieldAccessor.ofBeanProperty())
.defineMethod("setName", void.class, Visibility.PUBLIC)
.withParameter(String.class)
.intercept(FieldAccessor.ofBeanProperty())
.make()
.load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
AnnotationDescription repositoryAnnotation = AnnotationDescription.Builder.ofType(Repository.class)
.build();

TypeDescription.Generic genericType = TypeDescription.Generic.Builder
.parameterizedType(JpaRepository.class, type, Long.class)
.annotate(repositoryAnnotation)
.build();
Class<? extends Object> repository = new ByteBuddy()
.makeInterface()
.implement(genericType)
.name("CustomRepository")
.make()
.load(Controller.class.getClassLoader())
.getLoaded();

正确创建自定义实体和相应的自定义JPA存储库后,使用ByteBuddy转换服务类,自动连接新加载的实体。

builder = builder.defineField("customRepository", repo, Visibility.PUBLIC)
.annotateField(AnnotationDescription.Builder.ofType(Autowired.class)
.build());

现在,由于这是一个我们没有提供任何具体实现的接口[Spring将提供适当的实现],我们将需要一个BeanFactoryPostProcessor。

@Slf4j
@Configuration
public class DynamicJpaBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
.rootBeanDefinition(JpaRepositoryFactoryBean.class).addConstructorArgValue("your.custom.repository.classname");
((DefaultListableBeanFactory) configurableListableBeanFactory).registerBeanDefinition("your.custom.repository.classname", beanDefinitionBuilder.getBeanDefinition());
log.info("Registered the {} bean for {} successfully", JpaRepositoryFactoryBean.class.getSimpleName(),
"your.custom.repository.classname");
}
}

希望这对你有所帮助。当然,您将需要转换您的服务类,以便使用注入的存储库bean添加方法。

最新更新