【发布时间】:2016-09-26 04:13:56
【问题描述】:
我正在 Web 环境中使用 Spring Framework 4.3.3:
我有两种情况:
RootApplicationContextServletApplicationContext
我知道ServletApplicationContext 包含有关Web 端的所有bean,例如@Controller。此外ServletApplicationContext 能够从RootApplicationContext 访问所有上下文或bean,例如@Service, @Repository 等。直到这里我都很好。
注意它也适用于@Configuration 类。 (基础设施)
因此有了前面的介绍,我们可以这样想:
-
ServletApplicationContext-->RootApplicationContext
需要考虑的重要一点是,逆向是不可能的。
因此
-
RootApplicationContext-->ServletApplicationContext
不可能。它有道理,还可以。服务器端不应该访问Web端
关于 AspectJ。我有以下内容:
@Configuration
@EnableAspectJAutoProxy
public class AopConfig {
}
这里有一点很重要:
-
AopConfig被RootApplicationContext扫描- 我相信
ServletApplicationContext可以通过RootApplicationContext的访问权限引用@Configuration
- 我相信
好的,当我运行我的 @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/URI 执行 Controller 时,预期的行为或过程可以正常工作。但是关于通过AOP + logging的AOP会发生以下过程:
-
@Service->@Repository
@Controller 不会出现在输出中。预期的流程应该是:
-
@Controller->@Service->@Repository
那么为什么在测试中工作而不是在生产中呢?
我已经做了一个研究,我发现了这两个帖子:
实际上他们说带有@EnableAspectJAutoProxy 的@Configuration 类应该通过ServletApplicationContext 而不是通过RootApplicationContext 进行扫描
即使是真的(根据新的实验),请考虑在没有 Web 环境的情况下测试服务器端。
对于其他关于基础设施的@Beans,通过@Configuration 已经解释了关于ServletApplicationContext --> RootApplicationContext 的关系如何按预期工作。只是用AOP才有这种情况。
问题 01:那么为什么会有这种行为呢?
问题 02:如何保持AopConfig 被RootApplicationContext 扫描并获得预期的生产行为?
注意如果AopConfig 被ServletApplicationContext 扫描。以下关于测试的内容对于服务器端@ContextConfiguration(classes={RootApplicationContext.class, AopConfig.class} ) 是有效的强制。看到AopConfig.class的添加,但我认为AopConfig应该被RootApplicationContext扫描。
【问题讨论】:
标签: spring spring-mvc spring-aop spring-java-config spring-aspects