我正在 Web 环境中使用 Spring Framework 4.3.3:
我有两个背景:
RootApplicationContext
ServletApplicationContext
我知道ServletApplicationContext
包含关于Web端的所有bean,例如@Controller
。此外ServletApplicationContext
能够访问所有上下文或beanRootApplicationContext
例如@Service, @Repository
等等,直到这里我都很好。
Note它适用于@Configuration
类也。 (基础设施)
因此,根据前面的介绍,我们可以这样思考:
-
ServletApplicationContext
--> RootApplicationContext
需要考虑的重要一点是,逆矩阵是not可能的。
所以
-
RootApplicationContext
--> ServletApplicationContext
is not可能的。它有道理而且还可以。服务器端不应该访问Web端
关于 AspectJ。我有以下内容:
@Configuration
@EnableAspectJAutoProxy
public class AopConfig {
}
这里有一个重要的一点:
- This
AopConfig
is scanned by RootApplicationContext
- 我相信
ServletApplicationContext
可以参考一下@Configuration
通过访问RootApplicationContext
好的,当我运行我的@Test
方法。
当我从服务器端执行测试类时,我使用
-
@ContextConfiguration(classes={RootApplicationContext.class} )
- Only
RootApplicationContext
而且 AOP 工作得很好。我可以通过确认AOP + logging
过程如下:
当我从 Web 端执行测试类时,我使用:
-
@ContextConfiguration(classes={RootApplicationContext.class, ServletApplicationContext.class})
-
RootApplicationContext
and 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 aController
执行了预期的行为或流程工作正常。但是关于AOP通过AOP + logging
发生以下过程:
@Controller
不会出现在输出中。预期的流程应该是:
-
@Controller
-> @Service
-> @Repository
那么为什么在测试中有效而不在生产中有效呢?
我已经做了研究,发现了这两个帖子:
- Spring AOP 关于带注释控制器的建议 https://stackoverflow.com/questions/3310115/spring-aop-advice-on-annotated-controllers
- AspectJ 不适用于 Spring @Controller 方法 https://stackoverflow.com/questions/27290247/aspectj-does-not-work-on-spring-controller-methods
实际上他们说@Configuration
与 一起上课@EnableAspectJAutoProxy
应该扫描通过ServletApplicationContext
并且不通过RootApplicationContext
即使这是真的(根据新的实验),请考虑服务器端应该在没有 Web 环境的情况下进行测试。
对于他人@Bean
关于基础设施@Configuration
该关系已经解释过ServletApplicationContext --> RootApplicationContext
工作效果与预期一致。正好用AOP就有这种情况。
问题01: 那么为什么会有这种行为呢?
问题02: 怎么保留AopConfig
扫描者RootApplicationContext
并获得预期的生产行为?
Note if AopConfig
被扫描者ServletApplicationContext
。以下有关测试的内容是有效的和强制性的对于服务器端@ContextConfiguration(classes={RootApplicationContext.class, AopConfig.class} )
。请参阅添加AopConfig.class
但我觉得AopConfig
应通过扫描RootApplicationContext
.