Java 如何创建现有注释的快捷方式?

Java 如何创建现有注释的快捷方式?,java,scala,annotations,Java,Scala,Annotations,在我的代码中,我多次使用以下注释: @JsonSerialize(using = classOf[CustomColorRGBASerializer]) 为了保持代码简短,我想创建一个快捷方式,例如: class JsonSerializeARGB extends @JsonSerialize(using = classOf[CustomColorRGBASerializer]) 然后我可以将其用作新的@JsonSerializeARGB注释 我可以使用注释,但我不知道如何定义它们,因此

在我的代码中,我多次使用以下注释:

@JsonSerialize(using = classOf[CustomColorRGBASerializer])
为了保持代码简短,我想创建一个快捷方式,例如:

class JsonSerializeARGB
  extends @JsonSerialize(using = classOf[CustomColorRGBASerializer])
然后我可以将其用作新的
@JsonSerializeARGB
注释

我可以使用注释,但我不知道如何定义它们,因此我的尝试看起来很幼稚,显然是不正确的,但我希望它能贯穿其中

我已经读过和,但它们对我帮助不大,因为我不想创建一个全新的注释,而是“子类化”现有注释。这能做到吗


如果没有Scala解决方案,这样的事情可以在Java中完成吗?(无论如何,我正在使用的都是用Java定义的)。

看看Java,没有合理的方法可以做到这一点,因此,最简单的方法失败了。另一种可能性是使用反射将所有出现的
JsonSerializeARGB
替换为
JsonSerialize
,尽管这只在运行时有效,而不在编译时有效。但是Java反射API只支持,不支持添加它们

因此有两种理论方法:

  • 搞乱编译后的字节码,但没有人真的愿意这么做
  • 修改Jackson(或读取注释的任何其他库)以识别自定义
    JsonSerializeARGB
    注释
我不熟悉Scala,所以我不知道是否还有其他可用的选项。但我怀疑Scala是否提供了Java所没有的添加或扩展注释的方法。

恐怕存在(和Scala)语言机制。我认为唯一的解决办法是制作Scala

可用于Scala编译器。希望它们能包含在Scala 2.13中。要为宏天堂配置SBT,您可能需要遵循以下步骤。还有一个利用宏观天堂的项目

我相信这可以做得更好(尤其是DEF匹配),但类似于此的宏应该可以解决您的问题:

import scala.reflect.macros._
import scala.annotation.StaticAnnotation
import scala.language.experimental.macros

class JsonSerializeARGB extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro JsonSerializeARGBMacroImpl.impl
}

object JsonSerializeARGBMacroImpl extends JsonSerializeARGBMacro

class JsonSerializeARGBMacro {
  def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
      import c.universe._

      def modifiedDef(d: DefDef) = {
        val (mods, name, tparams, paramss, tpt, body) = try {
          val q"$mods def $name[..$tparams](...$paramss): $tpt = $body" = d
          (mods, name, tparams, paramss, tpt, body)
        } catch {
          case _: MatchError => c.abort(c.enclosingPosition, "Failed to match...")
        }

        //TODO there is a problem with modifiers
        c.Expr(q"""
          @JsonSerialize(using = classOf[CustomColorRGBASerializer])
          def $name[..$tparams](...$paramss): $tpt = $body
          """)
      }

      annottees.map(_.tree) match {
        case (d: DefDef) :: Nil => modifiedDef(d)
        case _ => c.abort(c.enclosingPosition, "Invalid annottee.")
      }
    }
 }

采取不同的方法。Jackson支持以编程方式定义序列化程序。因此,您可以定义自己的注释,然后使用反射查找注释中的所有类,并添加序列化程序映射

ObjectMapper mapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule("MyModule", new Version(1, 0, 0, null))
// use reflections to find all classes with Annotation the
for (classWithAnnotation <- classesWithAnnotation) {
  simpleModule.addSerializer(classWithAnnotation, new CustomColorRGBASerializer());
}
mapper.registerModule(simpleModule);
ObjectMapper mapper=new ObjectMapper();
SimpleModule SimpleModule=新的SimpleModule(“MyModule”,新版本(1,0,0,null))
//使用反射查找具有注释的所有类

对于(classWithAnnotation,以下是我尝试使用fasterXML库实现的示例:

1.创建自己的CustomSerializer 3.在CustomDTO或您的课堂上使用此选项,如下所示: 4.写下你的主要方法如下:
import com.fasterxml.jackson.annotation.jsonautodect;
导入com.fasterxml.jackson.core.JsonProcessingException;
导入com.fasterxml.jackson.databind.ObjectMapper;
导入com.fasterxml.jackson.databind.introspect.VisibilityChecker;
导入com.opera.oss.core.dto.CustomDTO;
公共类TestJson{
公共静态void main(字符串[]args)
{
CustomDTO responseDTO=新CustomDTO();
响应。设置颜色(“红色”);
回复至。setButtonColor(“蓝色”);
响应。setFrontColor(“黄色”);
System.out.println(“嘿”);
ObjectMapper om=新的ObjectMapper();
VisibilityChecker checker=om.getSerializationConfig().getDefaultVisibilityChecker();
om.setVisibilityChecker(checker.withFieldVisibility(jsonautodect.Visibility.ANY));
试一试{
System.out.println(om.writer().writeValueAsString(responseDTO));
}捕获(JsonProcessingException e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}

使用的库:fasterXML-2.5.0版本-jackson core、jackson data bind和jackson annotations

我认为jackson没有支持,但您正在寻找的概念称为meta-annotation。我认为步骤3和步骤4的可能重复是显而易见的,没有必要在答案中包含它们。我认为这样做会更容易没有他们我也能理解。是的,这很明显。为了完整起见,我把它包括在这里。
import java.io.IOException;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.core.JsonProcessingException;

public class CustomSerializer extends JsonSerializer<CustomDTO> {

@Override
public void serialize(CustomDTO value, JsonGenerator gen,
        com.fasterxml.jackson.databind.SerializerProvider serializers)
        throws IOException,
        JsonProcessingException {
    gen.writeStartObject();
    gen.writeStringField("AccentColor", value.getAccentColor());
    gen.writeStringField("ButtonColor", value.getButtonColor());
    gen.writeEndObject();
}
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;

@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = CustomSerializer.class)
public @interface JsonSeriliazerCustom {}
@JsonSeriliazerCustom
public class CustomDTO {

    private String buttonColor;
    private String accentColor;
    private String frontColor;

    public String getButtonColor() {
        return buttonColor;
    }

    public void setButtonColor(String buttonColor) {
        this.buttonColor = buttonColor;
    }

    public String getAccentColor() {
        return accentColor;
    }

    public void setAccentColor(String accentColor) {
        this.accentColor = accentColor;
    }

    public String getFrontColor() {
        return frontColor;
    }

    public void setFrontColor(String frontColor) {
        this.frontColor = frontColor;
    }


}
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
import com.opera.oss.core.dto.CustomDTO;

public class TestJson {

    public static void main(String[] args)
    {
        CustomDTO responseDTO = new CustomDTO();
        responseDTO.setAccentColor("red");
        responseDTO.setButtonColor("blue");
        responseDTO.setFrontColor("yellow");
        System.out.println("hey");
         ObjectMapper om = new ObjectMapper();
         VisibilityChecker<?> checker = om.getSerializationConfig().getDefaultVisibilityChecker();
            om.setVisibilityChecker(checker.withFieldVisibility(JsonAutoDetect.Visibility.ANY));

            try {
                System.out.println(om.writer().writeValueAsString(responseDTO));
            } catch (JsonProcessingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

    }
}