Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在方面内可靠地自动关联成员-即使在上下文刷新之后?_Java_Spring_Dependency Injection_Aop_Aspectj - Fatal编程技术网

Java 如何在方面内可靠地自动关联成员-即使在上下文刷新之后?

Java 如何在方面内可靠地自动关联成员-即使在上下文刷新之后?,java,spring,dependency-injection,aop,aspectj,Java,Spring,Dependency Injection,Aop,Aspectj,我有一个AspectJ方面,我想在其中有@Autowired字段。假定默认情况下,方面是在Spring容器外部创建的单例,Spring不会管理方面的任何依赖项注入 在搜索时,遇到了同样的问题,并且在方面上使用@Configurable注释以某种方式神奇地允许Spring执行依赖项注入()。我仍然不完全清楚这种魔法是如何工作的,但它似乎工作得很好 现在,我的问题是,如果我刷新Spring上下文,Spring不会更新依赖项以指向新bean。这是我的单元测试中的一个问题。我有一个定义了@Dirties

我有一个AspectJ方面,我想在其中有
@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配置为原型。