我有一个基于xml-config的spring应用程序,其中一个bean需要构造函数参数一个com.typesafe.config.Config参数。为此,我们有一个@Configuration类,其中一个方法(注释为@Bean)返回一个com.typesafe.config.Config对象。
但是当spring开始时,它抱怨说“未能实例化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>以下是Spring的例外:
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谢谢。
发布于 2017-02-15 19:22:11
令人反感的是:
<beans:bean id="app-config" class="com.typesafe.config.Config"/>
因为您已经将其放入spring.xml中,所以Spring试图从Config实例化一个名为app-config的bean。但是Config是一个接口,所以Spring无法实例化它,因此出现了错误。
我认为,一旦删除了它,Spring就会选择使用getConfig实例化的getConfig。如果这不起作用,看看TSConfiguration是否正确地导入到spring.xml中。
发布于 2017-02-15 20:54:37
为了添加到另一个答案,您需要声明两次可能是同一个bean的内容。
在这里,您告诉Spring创建一个名为app-config的Config类型的bean
@Bean(name = "app-config")
public Config getConfig(){在这里,您正在尝试使用id Config创建另一个类型为app-config的bean。
<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。这个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>如果您像上面那样手动声明Config类,则不需要使用@Configuration.对其进行注释。该注释的要点是让组件扫描“查看”bean并实例化它。因为我们是手动的,所以不需要注释。
而且,为了完整起见,这是一个单元测试,它验证了所有的工作:
@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());
}
}https://stackoverflow.com/questions/42257343
复制相似问题