2

我正在为我的应用程序使用 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 ITD 是 CTW,我的观点也适用于这些方法。我假设我的方面是在 Roo 方面之前编织的,因此没有将 Roo 的 ITD 视为我班级的一部分。

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

我尝试添加@DeclarePrecedence到方面的顶部,但要么它没有按我希望的那样工作,要么我没有正确定义它,因为它没有任何区别。

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

1 回答 1

0

来自AspectJ 文档

AspectJ 5 允许使用代码样式或注释样式指定方面及其成员。无论您使用哪种风格,AspectJ 编织器都可以确保您的程序具有完全相同的语义。引用一句著名的广告活动的话,这是“一种选择,而不是妥协”。这两种风格可以在一个应用程序中混合,甚至可以在一个源文件中混合,尽管我们怀疑后一种混合在实践中是否会被推荐。

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

其他要尝试的事情是更改RequiredUserDetailsAspect 的包位置。这包括移动到 src/main/java 而不是 src/test/java (我记得在声明优先级时 Roo 上的测试文件夹的双波打开问题)。

祝你好运!

于 2014-04-07T10:40:09.783 回答