Java 如何在方面内可靠地自动关联成员-即使在上下文刷新之后?
我有一个AspectJ方面,我想在其中有Java 如何在方面内可靠地自动关联成员-即使在上下文刷新之后?,java,spring,dependency-injection,aop,aspectj,Java,Spring,Dependency Injection,Aop,Aspectj,我有一个AspectJ方面,我想在其中有@Autowired字段。假定默认情况下,方面是在Spring容器外部创建的单例,Spring不会管理方面的任何依赖项注入 在搜索时,遇到了同样的问题,并且在方面上使用@Configurable注释以某种方式神奇地允许Spring执行依赖项注入()。我仍然不完全清楚这种魔法是如何工作的,但它似乎工作得很好 现在,我的问题是,如果我刷新Spring上下文,Spring不会更新依赖项以指向新bean。这是我的单元测试中的一个问题。我有一个定义了@Dirties
@Autowired
字段。假定默认情况下,方面是在Spring容器外部创建的单例,Spring不会管理方面的任何依赖项注入
在搜索时,遇到了同样的问题,并且在方面上使用@Configurable
注释以某种方式神奇地允许Spring执行依赖项注入()。我仍然不完全清楚这种魔法是如何工作的,但它似乎工作得很好
现在,我的问题是,如果我刷新Spring上下文,Spring不会更新依赖项以指向新bean。这是我的单元测试中的一个问题。我有一个定义了@DirtiesContext(classMode=classMode.AFTER\u EACH\u TEST\u METHOD)
的类,表示我希望spring在每个测试方法之后刷新上下文。但是,如果它不更新方面的依赖项,那么在我的第一次测试之后的任何测试都会失败,因为引用的bean(第一次运行时自动连接的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
方法的aspect中放置一个断点,我可以看到userRepository
bean引用在两个单元测试之间是相同的,即使从日志中我可以看到Spring已经实例化了一个新的userRepository bean。因此,在第二次测试中,方面指向一个过时的bean
我如何指示Spring刷新它通过
@可配置实例化注入方面的依赖项?我经常想知道为什么它们不能让Spring更容易地管理方面
但是,为了让spring管理方面,您将以下内容放入xml中。。。不知道如何使用java配置
虽然我认为配置也应该起作用。。。尽管您可能存在生命周期冲突问题
<bean id="securityAspect"
class="com.afrozaar.ashes.core.security.AuthorizationAspect">
factory-method="aspectOf" autowire="byType" />
factory method=“aspectOf”autowire=“byType”/>
当方面编译器创建一个方面时,它会将“aspectOf”方法添加到类中。此方法允许访问作为方面的对象,并且在xml中使用此配置将使该对象在spring之前暴露给injection等。关于此问题,github存在一个10年的问题,尚未解决
我在这里发布了一个解决方法:
基本上,您可以注册一个测试执行侦听器,检查上下文是否已更改,并手动更新单例。谢谢。我刚刚也发现了这一点。我仍然不能完全确定为什么@Configurable
不起作用。对在应用程序上下文仍在进行时创建的bean使用Configurable是不可靠的。此外,它用于从中注入bean的上下文可能不正确。另一个问题是,可配置是通过方面完成的,因此您正在使用方面-不知道这是否可能可配置是针对非单音调的,而SpringBean配置为原型。