我有一个AspectJ方面,我想拥有@Autowired字段.鉴于默认情况下,方面是在Spring容器外部创建的单例,因此Spring不管理方面的任何依赖项注入.
在SO上搜索,Spring autowired bean for @Aspect aspect is null遇到了相同的问题,并且在方面使用@Configurable注释以某种方式神奇地允许Spring进行依赖项注入(see @codebrickie response).我仍不完全清楚该魔术的工作原理,但似乎效果很好.
现在,我的问题是,如果刷新Spring上下文,Spring不会更新依赖项以指向新bean.这是我的单元测试中的问题.我有一个定义了@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)的类,表示我想让Spring在每个测试方法之后刷新上下文.但是,考虑到它不会更新Aspect的依赖关系,我的第一个测试之后的任何测试都将失败,因为所引用的bean(第一次运行后会自动连接)不再有效.
样品测试班:
@DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD)
@Transactional
public class UserServiceImplTest extends TestBase {
@Test
@RequiredUserDetails(permissions={Permission.USER_LIST})
public void testFindUser() throws Exception {
User u = dod.getRandomUser();
long userId = u.getId();
User u2 = userService.findUser(userId);
assertThat(u2, equalTo(u));
}
@Test(expected=AccessDeniedException.class)
public void testFindUserWithoutPermissions() throws Exception {
User u = dod.getRandomUser();
long userId = u.getId();
User u2 = userService.findUser(userId);
assertThat(u2, equalTo(u));
}
}
外观片段:
@Configurable
@Aspect
public class RequiredUserDetailsAspect {
@Autowired UserRepository userRepository;
@Pointcut("execution(public * *(..)) && @annotation(org.junit.Test)")
public void testMethod() {};
/**
* Inject the specific permissions before test executes
*/
@Before("testMethod() && requiresPermission(requiredUserDetails)")
public void beforeTest( RequiredUserDetails requiredUserDetails){
authenticateUser( userRepository.findOne( requiredUserDetails.id ) );
}
...
...
...
}
如果我在beforeTest方法的方面中设置了断点,则可以看到在两个单元测试之间userRepository bean引用是相同的,即使从日志中可以看到Spring实例化了一个新的userRepository bean.因此,在第二次测试期间,该方面指向一个过时的bean.
如何指示Spring通过@Configurable实例刷新注入到方面中的依赖项?
解决方法:
我经常想知道为什么他们没有让Spring更轻松地管理方面.
但是要使这一方面在spring的管理下,您将以下内容放入了xml …不知道如何使用java配置.
尽管我认为配置也应该工作……尽管您可能会遇到生命周期冲突的问题.
<bean id="securityAspect"
class="com.afrozaar.ashes.core.security.AuthorizationAspect">
factory-method="aspectOf" autowire="byType" />
方面编译器创建方面时,它将“ aspectOf”方法添加到类中.此方法可以访问作为方面的对象,并且在xml中具有此配置将在春季之前将该对象暴露给注入.