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