我正在Web环境中使用SpringFramework4.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,通过AOP + logging,会发生以下过程:
@Service -> @Repository输出不显示@Controller。预期的流程应是:
@Controller -> @Service -> @Repository那么,为什么在测试而不是在生产中工作呢?
我已经做了一项研究,我发现这两篇文章:
实际上,他们说带有@EnableAspectJAutoProxy的@EnableAspectJAutoProxy类应该通过ServletApplicationContext而不是RootApplicationContext进行扫描。
即使这是真的(根据新的实验),考虑到服务器端应该在没有Web环境的情况下进行测试。
对于其他关于通过@Configuration的基础设施的@Configuration,已经解释了关于ServletApplicationContext --> RootApplicationContext的关系是如何工作的。就在AOP有这种情况。
问题01:为什么会有这种行为?
问题02:如何保持AopConfig被RootApplicationContext扫描并得到预期的生产行为?
Note如果AopConfig被ServletApplicationContext扫描。下面的测试是有效的和服务器端的强制性( @ContextConfiguration(classes={RootApplicationContext.class, AopConfig.class} ) )。请参阅添加的AopConfig.class,但我认为AopConfig应该由RootApplicationContext扫描。
发布于 2016-09-26 05:32:22
答案是,测试环境中的@ContextConfiguration(classes={RootApplicationContext.class, ServletApplicationContext.class})和生产中的上下文继承不是一回事。在测试环境中,将RootApplicationContext和ServletApplicationContext作为测试应用程序上下文的一部分。在生产中使用继承而不是简单的包含,正如您在问题中所描述的那样。
似乎来自父上下文的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 {
...
}相关任务
https://stackoverflow.com/questions/39694633
复制相似问题