[英]Call a method when object state changes
I am providing an annotation @validateName
which anyone can include in their code. 我提供了一个@validateName
注释,任何人都可以在其代码中包含该注释。 Suppose some one coded 假设有人编码
class Person {
@validateName
private String name;
....
}
Then they can call NameValidator.validate(personObject)
or some similar method to validate the field. 然后,他们可以调用NameValidator.validate(personObject)
或其他类似方法来验证该字段。
I want to make sure that the name field is always in a valid state ie I want to call the validate()
method automatically whenever an annotated variable changes (no matter where it changes whether inside or outside the class). 我想确保name字段始终处于有效状态,即我想在带注释的变量发生更改时(无论在类的内部还是外部更改的位置validate()
自动调用validate()
方法。
I am willing to write a plugin that hooks into Eclipse and gets invoked during compilation phase. 我愿意编写一个挂接到Eclipse并在编译阶段被调用的插件。 Please provide some pointers where I can start looking for solutions. 请提供一些指示,让我可以开始寻找解决方案。
(I guess I have to implement some sort of AOP or should modify the bytecode using BCEL or something. I am not sure as I haven't tried both.) (我想我必须实现某种AOP或应该使用BCEL之类的东西来修改字节码。我不确定,因为我没有尝试过两者。)
With AspectJ you can do this: 使用AspectJ,您可以执行以下操作:
Annotation 注解
package de.scrum_master.aop.app;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidateName {}
Driver class 驾驶舱
package de.scrum_master.aop.app;
public class Application {
private int id;
@ValidateName
private String firstName;
@ValidateName
private String lastName;
private String placeOfBirth;
public Application(int id, String firstName, String lastName, String placeOfBirth) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.placeOfBirth = placeOfBirth;
}
@Override
public String toString() {
return "Application [id=" + id + ", firstName=" + firstName
+ ", lastName=" + lastName + ", placeOfBirth=" + placeOfBirth
+ "]";
}
public static void main(String[] args) {
System.out.println(new Application(1, "Galileo", "Galilei", "Pisa, Italy"));
System.out.println(new Application(2, "Isaac", "Newton", "Woolsthorpe-by-Colsterworth, United Kingdom"));
System.out.println(new Application(3, "Albert", "Einstein", "Ulm, Germany"));
System.out.println(new Application(4, "Werner", "Heisenberg", "Würzburg, Germany"));
}
}
Validator aspect 验证者方面
package de.scrum_master.aop.aspect;
import java.util.Random;
import de.scrum_master.aop.app.ValidateName;
public aspect NameValidator {
void validate(String name) {
if (new Random().nextBoolean())
throw new RuntimeException("Invalid name " + name);
}
void around(String name) : set(@ValidateName * *.*) && args(name) {
//System.out.println(thisJoinPointStaticPart);
System.out.print("Validating name " + name);
try {
validate(name);
System.out.println(" -> OK");
proceed(name);
}
catch (Exception e) {
name = name.toUpperCase();
System.out.println(" -> " + e.getMessage() + " -> replaced by " + name);
proceed(name);
}
}
}
As you can see, my validator just randomly fails in ca. 如您所见,我的验证器在ca中随机失败。 50% of all cases based on a pseudo-random value. 所有案例中有50%基于伪随机值。 When it does, it just replaces the "invalid" name by a capitalised version. 当这样做时,它只是将大写版本替换为“无效”名称。 The output looks like a variation of this: 输出看起来像这样:
Validating name Galileo -> OK
Validating name Galilei -> Invalid name Galilei -> replaced by GALILEI
Application [id=1, firstName=Galileo, lastName=GALILEI, placeOfBirth=Pisa, Italy]
Validating name Isaac -> Invalid name Isaac -> replaced by ISAAC
Validating name Newton -> Invalid name Newton -> replaced by NEWTON
Application [id=2, firstName=ISAAC, lastName=NEWTON, placeOfBirth=Woolsthorpe-by-Colsterworth, United Kingdom]
Validating name Albert -> OK
Validating name Einstein -> Invalid name Einstein -> replaced by EINSTEIN
Application [id=3, firstName=Albert, lastName=EINSTEIN, placeOfBirth=Ulm, Germany]
Validating name Werner -> OK
Validating name Heisenberg -> Invalid name Heisenberg -> replaced by HEISENBERG
Application [id=4, firstName=Werner, lastName=HEISENBERG, placeOfBirth=Würzburg, Germany]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.