我试图在设置字段值时修改它。我正在尝试使用 Spring AOP。这是到目前为止我的代码
// Translate class
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Translate {
}
//Aspect class
@Aspect
@Component
public class TranslationAspect {
@Autowired
private TranslationService translationService;
@Pointcut("@annotation(com.proj.si.api.annotations.Translate)")
public void translateField() {
}
@AfterReturning(pointcut = "translateField()", returning = "target")
public void translate(Object target) throws IllegalAccessException {
Field[] fields = target.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Translate.class)) {
field.setAccessible(true);
Object value = field.get(target);
if (value instanceof String) {
String translatedValue = translationService.getTranslation((String) value);
field.set(target, translatedValue);
}
}
}
}
}
//Config class
@Configuration
@EnableAspectJAutoProxy
public class AspectConfig {
}
// POJO
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ResponseObt implements Serializable {
@Translate
private String name;
我认为这段代码在调用字段的 getter 时进行拦截(这不起作用)。但是,我想修改此代码以用于设置器
首先,AOP只能应用于方法。
其次,修改返回值时,只能改变原对象的属性,而不能改变对象的引用(因此,如果方法的返回值是String,则无法修改)。这是一个例子:
正确
@AfterReturning(value = "pointCut()", returning = "obj")
public Object doAfterReturning(JoinPoint joinPoint, Object obj) {
User user = (User)obj;
user.setName("test");
return user;
}
不正确
@AfterReturning(value = "pointCut()", returning = "obj")
public Object doAfterReturning(JoinPoint joinPoint, Object obj) {
User user = new User();
obj = user;
return obj;
}
@annotation()
切入点目标是注释方法的执行,即您使用了错误的切入点指示符。你需要的是 set()
,但是 Spring AOP 中没有这个。您需要切换到原生 AspectJ,这最容易通过 -javaagent:/path/to/aspectjweaver.jar
实现。
资源:
set(Signature)
set(FieldPattern)
set(@Cachable * *)