2017-10-13 78 views
0

我想在我的Spring配置XML文件中引用Java配置类,但失败了,请参阅我下面的代码:引用JavaConfig在XML配置失败

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

} 

爪哇配置类:

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[email protected]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) 

所以从输出我们可以看到弹簧配置xml文件是由Spring框架找到的,因为我们得到的输出是“This is bean 3”,但是其他2个bean“bean1”和“bean2”不能被找到,即使我把合格BeanConfig类的名称作为BeanConfig.xml文件中bean元素的class属性的值。

我的问题是Spring为什么找不到Bean定义,该如何解决?

回答

1

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

,一旦你在乌尔XML添加右键扫描包,它会扫描并获得BeanConfig文件作为配置类将创建bean2并扫描包(冗余包)

通过分量扫描

@Configuration是间使用了@Component注解,因此 @Configuration类是用于组分扫描 (通常使用Spring XML的元素)和 候选因此也可以采取@自动装配Autowired/@的优点注入等的y 定期@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

+0

我想我已经加入@Configuration @ComponentScan(basePackages = {“c2_5_2.ref.javaconfig.from.xml”}) 在BeanConfig的那意味着告诉弹簧该类是一个配置类,应该扫描那些顶端类包含在c2_5_2.ref.javaconfig.from.xml包 – user2575502

+0

@ user2575502我已经更新了我的答案,就像我说的你只是创建一个普通的bean,spring并不认为它是一个配置bean,我已经说过如何使它作为我更新的答案中的配置bean。 –

+0

非常感谢,看起来书籍春天在行动,第4版(第62页)错过了你在这里说的。 – user2575502