i具有一个基于XML-Config的Spring应用程序,其中我的一个bean需要作为constructor参数a com.typesafe.config.config参数。为此,我们有一个@configuration类,其中一种方法(注释为@bean)返回com.typesafe.config.config对象。
但是当春季开始时,抱怨"无法实例化[com.typesafe.config.config]:指定的类是接口"
如何通过XML将getConfig返回对象返回构造函数?
这是简化的代码段,以摆脱应用程序逻辑:
import com.typesafe.config.Config;
...
public class myFilter implements Filter {
public myFilter(Config aconfig) {
...
}
}
然后,我有一个Javaconfig类,如下所示,我需要在MyFilter构造函数中注入bean:
@org.springframework.context.annotation.Configuration
public class TSConfiguration {
...
@Bean(name = "app-config")
public Config getConfig() {
...
}
}
我已经放入spring.xml文件以下内容:
<beans:bean class="TSConfiguration" />
<beans:bean id="app-config" class="com.typesafe.config.Config"/>
<beans:bean id="theFilter" class="myFilter">
<beans:constructor-arg index="0" ref="app-config"/>
</beans:bean>
这是春季的例外:
15-Feb-2017 13:19:55.463 SEVERE [localhost-startStop-1] org.springframework.web.context.ContextLoader.initWebApplicationContext Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'app-config' defined in ServletContext resource [/WEB-INF/spring-security.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.typesafe.config.Config]: Specified class is an interface
thanx。
有问题的行是:
<beans:bean id="app-config" class="com.typesafe.config.Config"/>
由于您已将其放在 spring.xml 中,因此Spring试图从Config
实例化称为app-config
的BEAN。但是Config
是一个接口,因此Spring无法实例化,因此错误。
我认为,一旦您删除它,Spring将选择使用getConfig
实例化的@Bean
。如果那不起作用,请查看TSConfiguration
是否正确导入您 spring.xml 。
要添加到另一个答案中,您正在宣布可能是两次相同的bean。
在这里,您告诉Spring使用名称app-config
:
@Bean(name = "app-config")
public Config getConfig(){
在这里,您正在尝试使用ID app-config
创建另一个类型Config
的豆。
<beans:bean id="app-config" class="com.typesafe.config.Config"/>
如果您在javaconfig中声明bean,则不必在XML中再次声明它,反之亦然(假设您的意图是具有该类型的单个bean)。
,正如已经指出的那样,您无法实例化接口。
更新:
我基本上要忽略您发布的代码,因为似乎对注释的工作和如何使用它们存在误解。
首先,如果您想在纯XML中执行所有操作,则不能这样做:
<beans:bean id="app-config" class="com.typesafe.config.Config"/>
您需要对该接口进行具体的实现。但是,根据您发布的内容,您使用了您正在使用的配置类。让我们从此开始:
package com.testpackage;
@Configuration
public class Config {
@Bean
public SomeInterface someImplementation(){
return new SomeInterface() {
@Override
public String implementation() {
return "String";
}
};
}
}
这说创建了SomeInterface
类型的豆。此bean的名称将继承方法名称someImplementation
,因此手动给出名称是没有意义的。请注意,在返回接口时,我们正在创建一个匿名类并返回。
接下来,我们将查看上述XML:
<beans>
<context:component-scan base-package="com.testpackage"/>
<bean class="com.testpackage.ConcreteClass">
<constructor-arg index="0" ref="someImplementation"/>
</bean>
</beans>
请注意,我们正在扫描(context:component-scan
)包含配置的软件包。如果我们使用@Configuration
注释,则可以进行组件扫描。
下面的示例执行相同的事情,但只需手动声明配置bean:
<beans>
<bean class="com.testpackage.Config"/>
<bean class="com.testpackage.ConcreteClass">
<constructor-arg index="0" ref="someImplementation"/>
</bean>
</beans>
如果您手动声明上面的配置类,您不需要用@Configuration
注释它。该注释的重点是要进行组件扫描以"查看"豆并实例化。由于我们正在手动进行,因此不需要注释。
,为了完整,这是一个单位测试,验证一切有效:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:META-INF/appContextTest.xml"})
public class SomeTester {
@Autowired
ConcreteClass concreteClass;
@Test
public void test(){
assertEquals("String", concreteClass.impl.implementation());
}
}