为什么我的切入点没有建议另一方面声明的方法?

时间:2014-04-04 01:27:36

标签: java aop aspectj spring-roo pointcut

我正在为我的应用程序使用Roo和编译时编织。 Roo生成的其中一个类是我的UserIntegrationTest

@RooIntegrationTest(entity = User.class)
@WebAppConfiguration
@ActiveProfiles("test")
@DirtiesContext
@RequiredUserDetails(roles=Role.ROOT)
public class UserIntegrationTest {
    @Test
    public void myTestMethod(){

    }
}

大多数代码都在Roo生成的ITD中:

privileged aspect UserIntegrationTest_Roo_IntegrationTest {

    declare @type: UserIntegrationTest: @RunWith(SpringJUnit4ClassRunner.class);

    declare @type: UserIntegrationTest: @ContextConfiguration(locations = "classpath*:/META-INF/spring/applicationContext*.xml");

    declare @type: UserIntegrationTest: @Transactional;

    @Autowired
    UserDataOnDemand UserIntegrationTest.dod;

    @Autowired
    UserService UserIntegrationTest.userService;

    @Autowired
    UserRepository UserIntegrationTest.userRepository;

    @Test
    public void UserIntegrationTest.testCountAllUsers() {
        Assert.assertNotNull("Data on demand for 'User' failed to initialize correctly", dod.getRandomUser());
        long count = userService.countAllUsers();
        Assert.assertTrue("Counter for 'User' incorrectly reported there were no entries", count > 0);
    }

    ...
    ...
    ...

}

我已经编写了自己的方面来处理我的@RequiredUserDetails注释。我的切入点指定了使用@Test注释的类中的任何@RequiredUserDetails方法。尽管切入点适用于主类中声明的任何方法(即:MyTestMethod()),但它并没有选择ITD中的任何方法。

@Aspect
public class RequiredUserDetailsAspect {
    /**
     * Defines any public <code>@Test</code> method
     */
    @Pointcut("execution(public * *(..)) && @annotation(org.junit.Test)")
    public void testMethod() {};

    /**
     * Anything with the {@link RequiredUserDetails} annotation on the method
     */
    @Pointcut("@annotation(RequiredUserDetails)")
    public void annotatedMethod(){};

    /**
     * Anything with the {@link RequiredUserDetails} annotation on the class
     */
    @Pointcut("@within(RequiredUserDetails)")
    public void annotatedClass(){};


    @Before("testMethod() && (annotatedClass() || annotatedMethod())")
    public void authenticateUser(JoinPoint jp){
        // check for any class annotations
        }
}

我原本预计,鉴于Roo ITDs是CTW,我的方面也适用于这些方法。我假设我的方面是在Roo方面之前编织的,因此不会将Roo的ITD视为我班级的一部分。

有没有办法确保Roo的ITD在我自己的方面之前编织,或者确保我的切入点也适用于Roo ITD?

我已经尝试将@DeclarePrecedence添加到方面的顶部,但要么它不能正常工作,要么我的定义不正确,因为它没有任何区别。

@Aspect
@DeclarePrecedence("**.*Roo*, RequiredUserDetailsAspect")
public class RequiredUserDetailsAspect {
  ...
  ...
}

1 个答案:

答案 0 :(得分:0)

来自AspectJ documentation

  

AspectJ 5允许使用代码样式或注释样式指定方面及其成员。无论你喜欢哪种风格   使用时,AspectJ weaver确保您的程序具有完全相同的功能   相同的语义。引用一个着名的广告活动,“a   选择,而不是妥协“。这两种风格可以混合在一起   应用程序,甚至在单个源文件中,尽管我们怀疑   后一种混合物将在实践中推荐。

阅读它我认为混合切入点样式不是问题,但我认为值得尝试将此方面改为代码样式而不是注释方式。

尝试的其他方法是更改​​RequiredUserDetailsAspect的包位置。这包括进入src / main / java而不是src / test / java(当声明优先级时,我可以记住Roo上测试文件夹的双波问题)。

祝你好运!