2

我在 Web 环境中使用 Spring Framework 4.3.3:

我有两种情况:

  • RootApplicationContext
  • ServletApplicationContext

我知道其中ServletApplicationContext包含有关 Web 端的所有 bean,例如@Controller. 此外ServletApplicationContext,还能够从RootApplicationContext例如@Service, @Repository等访问所有上下文或 bean。直到这里我都很好。

请注意,它也适用于@Configuration课程。(基础设施)

因此,结合前面的介绍,我们可以这样思考:

  • ServletApplicationContext-->RootApplicationContext

需要考虑的重要一点是,反过来是不可能的。

所以

  • RootApplicationContext-->ServletApplicationContext

不可能的。它有道理,还可以。服务器端不应访问 Web 端

关于 AspectJ。我有以下内容:

@Configuration
@EnableAspectJAutoProxy
public class AopConfig {

}

这里有一个重点:

  • AopConfig是由扫描的RootApplicationContext
    • 我相信ServletApplicationContext可以@Configuration通过访问RootApplicationContext

好的,当我运行我的@Test方法时。

当我从服务器端执行测试类时,我使用

  • @ContextConfiguration(classes={RootApplicationContext.class} )
    • 仅有的RootApplicationContext

AOP 工作正常。我可以通过AOP + logging以下过程确认:

  • @Service->@Repository

当我从 Web 端执行测试类时,我使用:

  • @ContextConfiguration(classes={RootApplicationContext.class, ServletApplicationContext.class})
    • RootApplicationContext ServletApplicationContext

AOP 工作正常。我可以通过AOP + logging以下过程确认:

  • @Controller-> @Service->@Repository

现在生产我有:

public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[]{RootApplicationContext.class};
    }

   @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[]{ServletApplicationContext.class};
    }

但是,当我将项目导出为.war文件并通过 URL/URIController执行时,预期的行为或过程可以正常工作。但是关于 AOP 通过AOP + logging以下过程发生:

  • @Service->@Repository

@Controller不会出现在输出中。预期的流程应该是:

  • @Controller-> @Service->@Repository

那么为什么在测试中工作而不是在生产中呢?

我已经做了一个研究,我发现了这两个帖子:

实际上,他们说应该扫描@Configuration类而不是通过@EnableAspectJAutoProxyServletApplicationContextRootApplicationContext

即使这是真的(根据新的实验),请考虑在没有 Web 环境的情况下测试服务器端。

对于其他@Bean关于基础设施的信息,通过@Configuration已经解释过的关于ServletApplicationContext --> RootApplicationContext如何预期工作的关系。只是用AOP就有这种情况。

问题 01:那么为什么会出现这种行为?

问题02:如何保持AopConfig扫描RootApplicationContext并获得生产的预期行为?

注意是否AopConfig被 扫描ServletApplicationContext。以下关于测试的内容对于服务器端是有效且强制性@ContextConfiguration(classes={RootApplicationContext.class, AopConfig.class} )的。看到加法AopConfig.class但是我觉得AopConfig应该被扫描RootApplicationContext

4

1 回答 1

4

答案是@ContextConfiguration(classes={RootApplicationContext.class, ServletApplicationContext.class})在测试环境和生产环境中的上下文继承不是一回事。在测试环境中,您包含RootApplicationContextServletApplicationContext作为测试应用程序上下文的一部分。正如您在问题中描述的那样,在生产中使用继承而不是简单的包含。

似乎父上下文中的BeanFactoryPostProcessor@EnableAspectJAutoProxy在您的情况下)未应用于子上下文。要使其在生产中工作,您也必须@EnableAspectJAutoProxy在子上下文中明确定义。

在这种情况下,Spring 上下文定义应该如下代码所示:

@Configuration
@Import(AopConfig.class)
public class RootApplicationContext {
    ...
}

@Configuration
@Import(AopConfig.class)
public class ServletApplicationContext {
    ...
}

或者

@Configuration
@ComponentScan(basePackageClasses={AopConfig.Class, ...})
public class RootApplicationContext {
    ...
}

@Configuration
@ComponentScan(basePackageClasses={AopConfig.Class, ...})
public class ServletApplicationContext {
    ...
}

相关任务

于 2016-09-26T05:32:22.537 回答