当前位置: 首页 > 知识库问答 >
问题:

Spring Boot类不可见ByteBuddy@Entity注释PathBeanDefinitionScanner basePackages扫描

濮阳靖
2023-03-14
     public Set<BeanDefinition> findCandidateComponents(String basePackage) {
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);

        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);

        if (isCandidateComponent(metadataReader)) {

        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ClassLoader cl = getClassLoader();
    Enumeration<URL> resourceUrls = (cl != null ? cl.getResources(path) : ClassLoader.getSystemResources(path));
MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);

上面的getMetadataReader方法调用最终以

final class SimpleMetadataReader implements MetadataReader 

它使用ASM ClassReader访问类和注释元数据。这显然找不到ByteBuddy放置的@Entity注释。

我不确定我是否应该以某种方式将Classloader链接到Bytebuddy中,或者重写Springs SimpleMetadataReader,以使我自己的实现得到Bytebuddy的支持。

public static void main(String[] args) {
    EntityAgent.install(ByteBuddyAgent.install());
    InversionContainer.startInversion(args);
}
**
* Transform all Non-Abstract Classes which extend BaseEntity
* to have the annotation Entity
*/
public class EntityAgent {

    /**
     * Installs the agent builder to the instrumentation API.
     */
    public static void install(Instrumentation inst) {
        createAgentBuilder().installOn(inst);
    }

    /**
      * Creates the AgentBuilder that will redefine any class extending BaseEntity
     */
    private static AgentBuilder createAgentBuilder() {
        return new AgentBuilder.Default()
                .with(toSystemError())
                .with(AgentBuilder.RedefinitionStrategy.REDEFINITION)
                .with(AgentBuilder.InitializationStrategy.SelfInjection.EAGER)
                .with(AgentBuilder.TypeStrategy.Default.REDEFINE)
                .type(getClassMatcher())
                .transform(getTransformer());
    }

    /**
     * Set Entity annotation on Class
     */
    private static AgentBuilder.Transformer getTransformer() {
        return (builder, typeDescription, classloader) -> builder.annotateType(AnnotationDescription.Builder.ofType(Entity.class).build());
    }

    /**
     * Find any non-abstract class that extends BaseEntity
     */
    private static ElementMatcher.Junction<TypeDescription> get ClassMatcher() {
        return ElementMatchers.isSubTypeOf(BaseEntity.class).and(ElementMatchers.not(ElementMatchers.isAbstract()));
    }
}

让我知道如果你想要更多的实现细节。我想把bytebuddy和spring集成起来,这样我就可以用spring组件注释来测试类。

共有1个答案

万承志
2023-03-14

“问题”在于Spring只关注原始类,而不是加载的类。Byte Buddy注册一个Java代理,该代理在加载类时转换类,但保留Spring Boot无法识别的原始类文件。

另一个问题是Spring在启动时和加载类之前会调查jar文件。这意味着当Spring收集其实体时,Byte Buddy代理甚至还没有活动。

相反,Spring应该调查加载的类,因为类加载器可能甚至不提供类文件,但我假设它们试图保留导致这种结果的类加载顺序。

 类似资料:
  • 我有很多Web服务在普通JDK上运行,我需要截取所有公共方法来做一些事情。有些方法正在使用@WebParam注释。用ByteBuddy子类化WebService会从覆盖方法中删除@WebParam注释,服务不再按预期工作。 这是签名样本 下面是我如何使用ByteBuddy 我知道有一种注释参数的方法,但是它需要关于方法参数的特殊知识(因为只有一些参数被注释)。我想做的只是要求ByteBuddy以与

  • 线程“main”java.lang.LinkageError:loader(sun/misc/launcher$AppClassLoader的实例):试图重复名称:“TestClass”的类定义 我正在尝试实现代理,如:easly-create-java-agents-with-bytebuddy中描述的示例所示 是否有一种方法可以加载Class对象而不导致此问题,或者使用传递给transform

  • 我观看了本Spring开机教程:https://javabrains.io/courses/spring_bootquickstart/lessons/Creating-a-Spring-Data-JPA-Repository 它将@Entity注释放在类名之前。当我试图在我的代码中这样做时,我得到一个错误,说“无法解析@Entity”。 这是我的pom.xml文件: 你知道有什么问题吗?

  • 创建类的首选方法是什么 不可变 可以使用Jackson进行序列化/反序列化 可读性强,样板文件水平低 最好是,我希望这样的东西能起作用: 然后将所有字段设置为。然而,这甚至不能编译(我不知道为什么)。使用 将编译,但仅生成

  • 问题内容: 我有几个需要用名称注释的类,因此我将注释定义为 现在,需要此注释的类定义为 我使用下面的代码来扫描注释 问题是返回的映射包含,但是我需要映射包含作为键,这是Annotation的值而不是bean名称。 有办法吗? 问题答案: 只需获取注释对象并提取值即可 让我知道是否不清楚。

  • 我正在使用MongoDB的springboot 2.3.0。注释对我不起作用。如果发生异常,则无法回滚事务。 任何帮助都将得到高度赞赏。 我的控制器类: 我的serviceImpl类 我的MongoConfig类