我正在开发一个方面,检查我的实体包的setter方法的字符串参数是否为空字符串,并用null
值替换它们。但不幸的是,我的方面效果不好:(。我想这是因为我的切入点定义,但我不确定。
我的方面如下:
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class EmptyStringToNullSetter {
private static final Logger LOGGER = LoggerFactory
.getLogger(EmptyStringToNullSetter.class);
public void check(final JoinPoint jp) {
LOGGER.debug(jp.getSignature().toLongString());
}
}
我的春季配置如下:
<bean id="emptyStringToNullSetter" class="de.foo.util.aop.parameter.EmptyStringToNullSetter" />
<aop:config>
<aop:pointcut id="entityStringSetter" expression="execution(* de.foo.entity.*.set*(..)) and args(java.lang.String)" />
<aop:aspect id="checkEmptyStringsAspect" ref="emptyStringToNullSetter">
<aop:before method="check" pointcut-ref="entityStringSetter" />
</aop:aspect>
</aop:config>
我的测试类看起来像:
import de.foo.entity.Period;
@ContextConfiguration(locations = { "/spring/test-util-context.xml" })
public class EmptyStringToNullSetterTest extends
AbstractJUnit4SpringContextTests {
@Test
public void testCheck() {
Period period = new Period();
period.setName("");
Assert.assertNull(period.getName());
}
}
当我执行测试时,方面不会拦截我的二传手。有谁知道为什么?!
干杯,
凯文
答案 0 :(得分:4)
由于您使用的是基于代理的AOP,因此该建议仅适用于Spring bean,而“period”对象不是bean。您需要将“句点”作为bean或使用AspectJ的基于编织的AOP。在任何一种情况下,您还需要使用周围的建议,而不是之前。
答案 1 :(得分:0)
使用基于Spring JDK代理的AOP,这种设计非常棘手且容易出错。
我在这里提到了这一点:http://doanduyhai.wordpress.com/2011/08/08/spring-aop-advices-on-setters-not-trigged/
基本上,使用Spring AOP定义的方面在运行时实现为包围原始目标的代理对象。
在bean生命周期中,Spring只在bean完全初始化后创建代理,例如在所有属性注入后,通过二传手。
因此,第一次调用setter时,它不会被通知拦截,因为代理尚不存在。
然而,所有后来对setter的调用都将被截获。
此外,请注意自我调用问题,例如:在另一个目标方法中调用setter()。