自定义属性注解应用
- 主要使用场景是需要设置根据属性值进行计算,代码重复性较强
eg:
根据 value 自动填充 value, 字典项、部门名称等
特殊值计算
- 此类方法的实现现在通过 ai 均可以实现,简单记录一下
eg:
场景: 计算费用信息不含税数值
a. 自定义注解
注意:如果只有一个属性直接命名为:String value() default "";
import java.lang.annotation.*;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AutoExtractTaxExclusive {
/**
* 含税金额字段名(默认:被标注字段自己)
*/
String from() default "";
/**
* 结果赋值的字段名(默认:被标注字段自己)
*/
String target() default "";
/**
* 税率字段名(默认:"taxRate")
*/
String taxRate() default "taxRate";
}
b. 数据填充方法
实现思路:
就是通过反射拿到所有属性,然后循环属性获取注解,根据注解属性实现功能,最后再通过反射赋值即可。
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class TaxExclusiveProcessor {
public static void process(Object targetObject) {
if (targetObject == null) return;
Class<?> clazz = targetObject.getClass();
for (Field field : clazz.getDeclaredFields()) {
AutoExtractTaxExclusive annotation = field.getAnnotation(AutoExtractTaxExclusive.class);
if (annotation == null) continue;
try {
// 解析注解字段名
String fromFieldName = annotation.from().isEmpty() ? field.getName() : annotation.from();
String targetFieldName = annotation.target().isEmpty() ? field.getName() : annotation.target();
String taxRateFieldName = annotation.taxRate();
// 获取含税金额
Field fromField = clazz.getDeclaredField(fromFieldName);
fromField.setAccessible(true);
BigDecimal taxIncludedAmount = (BigDecimal) fromField.get(targetObject);
// 获取税率
Field taxRateField = clazz.getDeclaredField(taxRateFieldName);
taxRateField.setAccessible(true);
BigDecimal taxRate = (BigDecimal) taxRateField.get(targetObject);
// 获取目标字段
Field targetField = clazz.getDeclaredField(targetFieldName);
targetField.setAccessible(true);
if (taxIncludedAmount != null && taxRate != null) {
BigDecimal rateDecimal = taxRate.multiply(new BigDecimal("0.01"));
BigDecimal denominator = BigDecimal.ONE.add(rateDecimal);
BigDecimal result = taxIncludedAmount.divide(denominator, 2, RoundingMode.HALF_UP);
targetField.set(targetObject, result);
}
} catch (Exception e) {
throw new RuntimeException("自动计算不含税金额失败: " + field.getName(), e);
}
}
}
}
c. 实际调用
public class InvoiceDTO {
private BigDecimal taxRate;
@AutoExtractTaxExclusive
private BigDecimal taxIncludedAmount;
@AutoExtractTaxExclusive(from = "taxIncludedAmount", target = "taxExclusiveAmount")
private BigDecimal taxExclusiveAmount;
}
TaxExclusiveProcessor.process(dto);