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

注释Spring bootstrap类并在其他地方实现注释

柳和怡
2023-03-14

我想做如下事情:-

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyCustomAnnotation {
    public String field1();
    public String[] list1();
}

@SpringBootApplication
@MyCustomAnnotation(field1 = "value1", list1 = { "list value 1", "list value2" })
public class Application {
    public static void main(String[] args){
        SpringApplication.run(Application.class, args);
    }
}

public class AnnotationImplementationClass {
    // Inject field1 and list1 values from @MyCustomAnnotation into this class
    private String field1;
    private String[] list1;
}

我想将AnnotationImplementationClass与被注释的类隔离开来,这样我就可以打包和分发自定义注释及其实现,从而允许开发人员使用@MyCustomAnnotation注释他们自己的spring boot应用程序类。

限制条件是我不知道Spring Boot类(在本例中为Application.java)的类名,显然我无权访问该类来修改它。我必须在运行时以某种方式获得访问权限,以便使用反射来获取自定义注释中的值。

我已经研究了试图演示BeanPostProcess使用的示例,但当它应用于包含@SpringBootApplication的java类时,我无法找到@MyCustomAnnoation。

共有2个答案

方权
2023-03-14

我终于自己解决了这个问题。以下是我的解决方案:-

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(AnnotationImplementationClass.class)
public @interface MyCustomAnnotation {
    public String field1();
    public String[] list1();
}


@SpringBootApplication
@MyCustomAnnotation(field1 = "field1 value", list1 = { "list1 value 1", "list1 value 2" })
public class Application
{
    public static void main(String[] args)
    {
        SpringApplication.run(Application.class, args);
    }
}

public class AnnotationImplementationClass implements ApplicationContextAware
{
    private String field1;
    private String[] list1;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
    {
        // Grab the beans from the app context that are annotated with my custom annotation
        Map<String, Object> beanMap = applicationContext.getBeansWithAnnotation(MyCustomAnnotation.class);
        Collection<Object> beans = beanMap.values();

        // There is a possibility that multiple beans are annotated with the annotation. I only annotated one bean
        // but I am using a "for" loop for illustration.
        for (Object bean : beans)
        {
            // Spring annotated classes are often proxied when Spring is initializing. I found that I was unable to get
            // the annotation and its parameter values from the proxy instance. I need to find the actual class that was
            // annotated using the the proxy as a start point. The following "if" clause illustrates the process.
            Class<? extends Object> annotatedClass = null;
            if (bean instanceof TargetClassAware)
            {
                annotatedClass = ((TargetClassAware) bean).getTargetClass();
            }
            else if (ClassUtils.isCglibProxy(bean))
            {
                annotatedClass = bean.getClass().getSuperclass();
            }
            else
            {
                annotatedClass = bean.getClass();
            }

            // Now I can get the annotation and its parameter values
            MyCustomAnnotation annotation = annotatedClass.getAnnotation(MyCustomAnnotation.class);
            field1 = annotation.field1();
            list1 = annotation.list1();

            // Since I only want one of the classes annotated by my custom annotation I break out of the loop
            break;
        }
    }
}

需要注意的几点:-

  • 在自定义注释界面上使用@import。这允许我将实现类挂接到Spring上下文中。不确定这是否是@import的正确使用,但它是我最终解决方案的关键。
  • 在实现类上使用"implements Application ContextAware"。这为我在Spring初始化期间进行控制提供了一个切入点。

希望这对其他人有帮助。

葛威
2023-03-14

Spring Boot Starter类包含“public static void main(String[]args)”方法。您可以通过反射来引用容器类。

这也许会帮助你。我不知道你的目标如何实现。但是你的自定义注释应该以最高优先级扫描。

 类似资料:
  • 问题内容: 我想创建一个自定义注释(使用Java),该注释将接受其他注释作为参数,例如: 但这会导致编译器错误“注释成员的类型无效”。 Object []也无效。 有什么方法可以做我想要的吗? 问题答案: 我本人就此提出针对此问题的解决方法: 好吧,我想要实现的是这样的: 拟议的解决方法: 用以下方法定义一个无参数构造函数的类(稍后将由您自己的注释处理器调用): 用法:

  • 对于用@X注释的类中的方法或用@X注释的方法,我需要一个切入点。我还需要注释对象。如果类和方法都被注释,我更喜欢将方法注释作为参数。 我尝试了以下操作,这会产生“绑定不一致”的警告。(为什么不直接将其设置为null?) 以下内容创建了“穿过切入点中的“||”的参数x的不明确绑定”警告。(在我看来,这不一定有意义:为什么不绑定第一个短路评估?) 如果存在类和方法注释,则将前面的尝试拆分为两个,自然会

  • 在Java中,我可以“实现”注释。 示例 Java 注释: 示例 Java“实现”: 尝试将其移植到 Kotlin 不起作用,因为它说注释是最终的,因此不能被继承,即以下内容将不起作用: 如何以Kotlin的方式“实现/扩展”注释?找不到Kotlin与Java在这方面存在差异的任何原因。欢迎任何关于如何解决这个问题的提示或任何说明为什么会这样的消息来源。 以下问题包含此星座的用例:使用带有成员的限

  • 我正在使用注释处理器来处理方法参数的注释。 用于参数的注释类型有一个注释@参数 现在,当注释处理器运行时,我想检查参数注释()是否有参数注释。我通过执行以下代码来实现这一点。 由于某种原因,arg始终为空。是否有注释未返回的原因?

  • 我已经编写了一个简单的注释处理器(只是为了好玩),它将生成一些我在以前的项目中编写的样板代码。它实际上通过收集活动类上的注释来生成如下所示的模块 但是,当我用dagger运行时,dagger似乎找不到我的注释处理器生成的类。虽然,类是生成的,并且存在于生成的目录中,我可以在源代码中使用它,但在编译时,dagger会产生以下异常。有什么专家建议吗? 这是主要的应用程序组件。 如果有人想做实验,这里有

  • 本文向大家介绍PowerShell单行注释、多行注释、块注释的方法,包括了PowerShell单行注释、多行注释、块注释的方法的使用技巧和注意事项,需要的朋友参考一下 PowerShell的注释符分为行注释符和块注释符。行注释符使用井号(#)引起一行;块注释符使用“<#”和 “#>”来引起一段注释。 行注释符 举例如下: 块注释符、多行注释 举例如下: 这是小编每次写脚本之前,都会定义的一段关于脚