我试图用AspectJ解决以下问题。
给定具有null @Embedded字段的实体类,当尝试使用getter访问该字段时,如果它为null,则首先将其实例化。即:这将确保getXXXX永远不会返回空值。
例如:
@Entity
public class MyClass {
@Id
private long id;
@Embedded
private Validity validity;
}
And Validity:
@Embeddable
public class Validity{
private long from;
private long to;
}
我无法弄清楚如何最好地编写before()建议。理想情况下,我试图避免使用反射,因为害怕减慢速度,但到目前为止,我能够提出的最好的是:
// define a pointcut for any getter method of a field with @Embedded of type Validity with any name in com.ia.domain package
pointcut embeddedGetter() : get( @javax.persistence.Embedded com.ia.domain.Validity com.ia.domain..* );
before() : embeddedGetter(){
String fieldName = thisJoinPoint.getSignature().getName();
Object obj = thisJoinPoint.getThis();
// check to see if the obj has the field already defined or is null
try{
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
if( field.get(obj) == null )
field.set(obj, new com.ia.domain.Validity() );
}
catch( IllegalAccessException | NoSuchFieldException e){}
}
但我的建议是使用反射来访问字段值。有没有办法在没有反思的情况下做到这一点?
答案 0 :(得分:1)
通过大约建议,只有在需要初始化时才能进行反射:
Object around(): embeddedGetter() {
Object value = proceed();
if (value == null) {
String fieldName = thisJoinPoint.getSignature().getName();
Object obj = thisJoinPoint.getThis();
try{
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value = new Validity() );
}
catch( IllegalAccessException | NoSuchFieldException e){e.printStackTrace();}
}
return value;
}