user2575502
user2575502

Reputation: 703

Referencing JavaConfig in XML configuration failed

I want to reference a java config class in my Spring config xml file, but failed, please see below my code:

Bean1 class :

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 class :

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 Class :

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 Class :

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>

Run Test method :

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

Get following output and error message:

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)

So from the output we can see the spring configuration xml file is found by spring framework because we got output "This is bean 3", but other 2 beans, "bean1" and "bean2" cannot be found even though I put the qualified name of BeanConfig class as a value to class property of the bean element in BeanConfig.xml file.

My concern is why spring cannot find the Bean definition, how to fix it?

Upvotes: 0

Views: 881

Answers (1)

Chi Dov
Chi Dov

Reputation: 1527

if you use xml as config file to load the context you need to add <context:component-scan base-package="c2_5_2.ref.javaconfig.from.xml" /> which will fix your problem. since you code just create the BeanConfig class as a bean but it doesn't know that it is a configuration and trigger the scan the package. because you just create a bean.

once you add context-scan-package in ur xml, it will scan and get the BeanConfig file as config class which will create the bean2 and scan the package (redundant package)

Via component scanning

@Configuration is meta-annotated with @Component, therefore @Configuration classes are candidates for component scanning (typically using Spring XML's element) and therefore may also take advantage of @Autowired/@Inject like any regular @Component. In particular, if a single constructor is present autowiring semantics will be applied transparently:

<?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>

update: if you want to create the bean as configuration file you can do:

Via Spring XML

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

see detail : how spring look for @Configuration

Upvotes: 1

Related Questions