簡體   English   中英

如何使用bytebuddy注冊自定義JPA接口

[英]How to register custom JPA interface using bytebuddy

我需要注冊一個從 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 轉換服務 class 自動裝配新加載的實體。

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");
    }
}

希望這對你有幫助。 當然,您需要轉換服務 class 以添加使用注入的存儲庫 bean 的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM