我一直在使用基于 XML 的配置——我们有一个使用 Spring 作为 DI 的 Vaadin 应用程序,但我们不感兴趣DispacherServlet
——只有根上下文,我们用它来注入全局(不是用户拥有的依赖项)。
它的工作方式
我已经定义root-context.xml
了包含内容的文件:
<context:annotation-config />
<context:spring-configured />
<context:load-time-weaver />
<context:component-scan base-package="com.example" />
我web.xml
的有:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
然后,我的一些类是用@Component
注释定义的,而另一些是用注释定义的@Configurable
(后者主要属于用户会话,因此每个使用new
关键字创建的实例都需要 DI)。
我有context.xml
文件:
<Loader delegate="false" loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader" />
并且spring-instrument-tomcat-3.2.1.RELEASE.jar
在Tomcat的lib
目录中。
所有依赖项都正确注入(使用@Autowire
)到我的@Configurable
类中。
它不起作用的方式
最近我试图摆脱root-context.xml
上下文初始化并将其移动到Java@Configuration
类。
我创建了一个类,如下所示:
@Configuration
@EnableSpringConfigured
@EnableLoadTimeWeaving
@ComponentScan("com.example")
public class BeansConfiguration
{
}
此外,我更改了web.xml
条目:
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.example.spring.BeansConfiguration</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
不幸的是,奇怪的事情开始发生。让我给你看一个例子。简化我的类结构如下所示:
@Component
public class ComponentA
{
}
@Configurable
public class BeanB
{
@Autowired
private ComponentA componentA;
}
@Configurable
public class BeanC
{
@Autowired
private ComponentA componentA;
private BeanB beanB;
public BeanC(BeanB beanB)
{
this.beanB = beanB;
}
}
@Configurable
public class Application
{
@Autowired
private ComponentA componentA;
public Application()
{
}
public void init()
{
BeanC beanC = new BeanC(new BeanB());
}
}
使用 XML 设置,当它工作时,ComponentA
Spring 会正确地将其注入到我的所有@Configurable
对象中。奇怪的是,只有注释的配置BeanC
并没有得到ComponentA
注入(它总是null
),但是BeanB
确实Application
得到了!
你有什么想法为什么会发生?一旦我注释掉行web.xml
以返回到我以前的(基于 XML 的)配置,一切都开始工作。
我很高兴的猜测是,XML Spring 条目比基于注释的条目更隐蔽地注册了一些东西。我花了半天的时间试图找出那可能是什么,但我放弃了。我将不胜感激任何建议。