如何从方法(@bean)返回接口(com.typesafe.config.config)的方法(@bean)中注入bea



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());
    }
}

相关内容

最新更新