我正在使用AspectJ在自定义PropertyChangeSupport引擎中编织任何使用@BindableClass标记的类。它查找用@BindableMethod标记的方法,并拦截'set'调用以触发propertyChangeListeners链。这一切都运行正常,但我只想拦截它具有值@BindableMethod(type = Type.SET)的方法,因为我在PCS之外使用此注释。我正在努力解决切入点的语法问题,如果有人可以帮助我,我会很感激。
我可以通过在我寻找字段名称时检查注释的值来破解它,但我更愿意让aspectJ查找为我做这个。我认为关键在于下面的'切入点'声明。
道歉,如果我描述得很严重,那么自从我使用AspectJ已经有几年了。我在Annotation查找周围找到了一些答案,但没有围绕注释值。
我的注释:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BindableMethod {
String fieldName();
Type type() default Type.SET;
public static enum Type {
GET, SET;
}
}
我的观点:
public aspect PropertySupportAspect {
/**
* Weave any class which is tagged with @BindableClass with NestedPropertyChangeSupport
*/
declare parents: @BindableClass * implements PropertySupport, IBindable;
NestedPropertyChangeSupport PropertySupport.support = new NestedPropertyChangeSupport(this);
public interface PropertySupport {
public void addPropertyChangeListener(PropertyChangeListener listener);
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener);
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener);
public void removePropertyChangeListener(PropertyChangeListener listener);
public boolean hasListeners(String propertyName);
public void firePropertyChange(Object b, String property, Object oldval, Object newval);
}
public PropertyChangeSupport PropertySupport.changeSupport() {
return support;
}
public void PropertySupport.addPropertyChangeListener(PropertyChangeListener listener) {
support.addPropertyChangeListener(listener);
}
public void PropertySupport.addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
support.addPropertyChangeListener(propertyName, listener);
}
public void PropertySupport.removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
support.removePropertyChangeListener(propertyName, listener);
}
public void PropertySupport.removePropertyChangeListener(PropertyChangeListener listener) {
support.removePropertyChangeListener(listener);
}
public boolean PropertySupport.hasListeners(String propertyName) {
return support.hasListeners(propertyName);
}
pointcut callSetter(PropertySupport b) :
call( @BindableMethod * *(..) )
&& target( b );
void around(PropertySupport b) : callSetter( b )
{
Field propertyField = getField(thisJoinPointStaticPart.getSignature());
try {
propertyField.setAccessible(true);
Object oldValue = propertyField.get(b);
proceed(b);
Object newValue = propertyField.get(b);
((PropertySupport) b).firePropertyChange(b, propertyField.getName(), oldValue, newValue);
} catch (Exception e) {
e.printStackTrace();
}
}
private Field getField(Signature signature) {
Field field = null;
try {
MethodSignature ms = (MethodSignature) signature;
Method m = ms.getMethod();
BindableMethod annotation = m.getAnnotation(BindableMethod.class);
field = signature.getDeclaringType().getDeclaredField(annotation.fieldName());
} catch (NoSuchFieldException nsfe) {
nsfe.printStackTrace();
}
return field;
}
public void PropertySupport.firePropertyChange(Object b, String property, Object oldval, Object newval) {
support.firePropertyChange(property, oldval, newval);
}
}
我的测试班:
@BindableClass
private class Child {
public static final String FLD_NAME = "name";
private String name;
@BindableMethod(fieldName = FLD_NAME)
public void setName(String name) {
this.name = name;
}
@BindableMethod(fieldName = FLD_NAME, type = Type.GET)
public String getName() {
return name;
}
}
答案 0 :(得分:1)
目前这是不可能的,但 aspectj-users 邮件列表上已经有人谈论:
您可能想要了解讨论,看看核心开发人员何时真正有时间适当地扩展AspectJ语法。
答案 1 :(得分:1)
pointcut callSetter(PropertySupport b, BindableMethod bm) :
call(@BindableMethod * *(..))
&& target(b)
&& @annotation(bm);
void around(PropertySupport b,BindableMethod bm) : callSetter( b,bm ){
bm.type();
}