在XML配置中引用JavaConfig失败

时间:2017-10-13 02:05:31

标签: java spring

我想在我的Spring config xml文件中引用一个java配置类,但是失败了,请看下面我的代码:

Bean1类:

package c2_5_2.ref.javaconfig.from.xml;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component("bean1")
public class Bean1 {
    @Autowired
    public Bean1(Bean2 bean2)
    {
        this.bean2 = bean2;
    }
    private Bean2 bean2;

    public Bean2 getBean2() {
        return bean2;
    }
}

Bean2类:

package c2_5_2.ref.javaconfig.from.xml;

import java.util.List;

public class Bean2 {
    private List<String> nameList;

    public List<String> getNameList() {
        return nameList;
    }

    public void setNameList(List<String> nameList) {
        this.nameList = nameList;
    }

    public void displayNames()
    {
        for(String name : nameList)
        {
            System.out.println(name);
        }
    }
}

Bean3类:

package c2_5_2.ref.javaconfig.from.xml;

public class Bean3 {
    private Bean1 b1;

    public Bean1 getB1() {
        return b1;
    }

    public void setB1(Bean1 b1) {
        this.b1 = b1;
    }

    public void introduce()
    {
        System.out.println("this is bean 3");
    }

}

Java Config类:

package c2_5_2.ref.javaconfig.from.xml;

import java.util.ArrayList;
import java.util.List;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages= {"c2_5_2.ref.javaconfig.from.xml"})
public class BeanConfig {

    @Bean(name="bean2")
    public Bean2 getBean2()
    {
        Bean2 b2 = new Bean2();
        List<String> nameList = new ArrayList<String>();
        nameList.add("Bitt");
        nameList.add("Rock");
        nameList.add("Lucas");
        nameList.add("Crius");
        b2.setNameList(nameList);
        return b2;
    }
}

BeanConfig.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans.xsd">
      <bean class="c2_5_2.ref.javaconfig.from.xml.BeanConfig"></bean>
      <bean id="bean3" class="c2_5_2.ref.javaconfig.from.xml.Bean3"></bean>


</beans>

运行测试方法:

private static void test3()
{
    ApplicationContext ctx = new ClassPathXmlApplicationContext("c2_5_2/ref/javaconfig/from/xml/BeanConfig.xml");
    Bean3 b3 = ctx.getBean(Bean3.class);
    b3.introduce();
    Bean1 b1 = ctx.getBean(Bean1.class);
}    

获取以下输出和错误消息:

Oct 13, 2017 9:55:16 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@6d9c638: startup date [Fri Oct 13 09:55:16 CST 2017]; root of context hierarchy
Oct 13, 2017 9:55:16 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [c2_5_2/ref/javaconfig/from/xml/BeanConfig.xml]
**this is bean 3**
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'c2_5_2.ref.javaconfig.from.xml.Bean1' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:348)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:335)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1101)
    at c2_5_2.ref.javaconfig.from.xml.Test_Driven.test3(Test_Driven.java:33)
    at c2_5_2.ref.javaconfig.from.xml.Test_Driven.main(Test_Driven.java:12)

所以从输出中我们可以看到spring框架xml文件是由spring框架找到的,因为我们得到了输出“这是bean 3”,但是其他2个bean,“bean1”和“bean2”找不到,即使我把BeanConfig类的限定名称,作为BeanConfig.xml文件中bean元素的class属性的值。

我担心的是为什么spring无法找到Bean定义,如何修复它?

1 个答案:

答案 0 :(得分:1)

如果您使用xml作为配置文件来加载您需要添加<context:component-scan base-package="c2_5_2.ref.javaconfig.from.xml" />的上下文,这将解决您的问题。因为您的代码只是将BeanConfig类创建为bean,但它不知道它是一个配置并触发扫描包。因为你只是创建一个bean。

一旦你在ur xml中添加了context-scan-package,它就会扫描并获取BeanConfig文件作为配置类,这将创建bean2并扫描包(冗余包)

通过组件扫描

  

@Configuration因此使用@Component进行元注释   @Configuration类是组件扫描的候选者   (通常使用Spring XML的元素)和   因此也可以像@任何一样利用@Autowired / @Inject   常规@Component。特别是,如果存在单个构造函数   自动装配语义将以透明方式应用:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans.xsd">
      <bean class="c2_5_2.ref.javaconfig.from.xml.BeanConfig"></bean>
      <bean id="bean3" class="c2_5_2.ref.javaconfig.from.xml.Bean3"></bean>

      <context:component-scan base-package="c2_5_2.ref.javaconfig.from.xml" />

</beans>

更新:如果您想将bean创建为配置文件,您可以这样做:

通过Spring XML

<beans>
    <context:annotation-config/>
    <bean class="c2_5_2.ref.javaconfig.from.xml.BeanConfig"/>
 </beans>

详见:how spring look for @Configuration