Autowire reference beans into list by type

后端 未结 2 562
花落未央
花落未央 2020-11-28 09:43

I have one class that has a list of objects of Daemon type.

class Xyz {    
    List daemons;
}

My spring config

相关标签:
2条回答
  • 2020-11-28 10:10

    It should work like this (remove the ArrayList bean from your XML):

    public Class Xyz {    
    
        private List<Daemon> daemons;
    
        @Autowired
        public void setDaemons(List<Daemon> daemons){
            this.daemons = daemons;
        }
    
    }
    

    I don't think there's a way to do this in XML.


    See: 3.9.2. @Autowired and @Inject:

    It is also possible to provide all beans of a particular type from the ApplicationContext by adding the annotation to a field or method that expects an array of that type:

    public class MovieRecommender {
    
      @Autowired
      private MovieCatalog[] movieCatalogs;
    
      // ...
    }
    

    The same applies for typed collections:

    public class MovieRecommender {
    
      private Set<MovieCatalog> movieCatalogs;
    
      @Autowired
      // or if you don't want a setter, annotate the field
      public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs) {
          this.movieCatalogs = movieCatalogs;
      }
    
      // ...
    }
    

    BTW, as of Spring 4.x, these lists can be ordered automatically using the @Ordered mechanism.

    0 讨论(0)
  • 2020-11-28 10:11

    Well, this can be achieved in two ways as stated in Spring Documentation.

    Below is the excerpt from the documentation.

    With byType or constructor autowiring mode, you can wire arrays and typed collections.

    1. autowire="byType"

    Autowiring using "byType" can be achieved if the type of the bean defined in the xml matches the type of list.

    Example:

    Motor.java

    package com.chiranth;
    public interface Motor 
    {
       public void start();
    }
    

    ElectricMotor1.java

    package com.chiranth;
    public class ElectricMotor1 implements Motor
    {
         public void start() 
         { 
             System.out.println("Motor 1 Started.");
         }
    }
    

    ElectricMotor2.java

    package com.chiranth;
    public class ElectricMotor2 implements Motor
    {
        public void start() 
        {
            System.out.println("Motor 2 Started.");
        }
    }
    

    TeslaModelX.java

    package com.chiranth;
    import java.util.List;
    public class TeslaModelX 
    {
        private List<Motor> motor;
    
        public List<Motor> getMotor()
        {
            return motor;
        }
    
        public void setMotor(List<Motor> motor) 
        {
            this.motor = motor;
        }
    
        public void goForward()
        {
            for(Motor m :motor)
                m.start();
            System.out.println("Going Forward.");
        }
    }
    

    Spring.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"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation = "http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="electricMotor1" class="com.chiranth.ElectricMotor1"/>
        <bean id="electricMotor2" class="com.chiranth.ElectricMotor2"/>
    
        <bean id="modelX" class="com.chiranth.TeslaModelX" autowire="byType"/>
    </beans>
    

    Test.java

    package com.chiranth;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    public class Test 
    {
        public static void main(String[] args) 
        {
            ApplicationContext context= new ClassPathXmlApplicationContext("Spring.xml");
            TeslaModelX modelx=(TeslaModelX)context.getBean("modelX");
            modelx.goForward();
        }
    }
    

    OUTPUT:

    Motor 1 Started.
    Motor 2 Started.
    Going Forward.
    

    2. autowire="constructor"

    Autowiring using "constructor" can be achieved if the type of the bean defined in the xml matches the type of the argument in the constructor.

    Example:

    Considering the above Motor.java , ElectricMotor1.java and ElectricMotor2.java.

    TeslaModelX.java

    package com.chiranth;
    import java.util.List;
    public class TeslaModelX 
    {
        private List<Motor> motor;
    
        public TeslaModelX(List<Motor> motor)
        {
            this.motor=motor;
        }
    
        public void goForward()
        {
            for(Motor m:motor)
                m.start();
            System.out.println("Going Forward.");
        }
    }
    

    Spring.xml

    <beans xmlns = "http://www.springframework.org/schema/beans"
       xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation = "http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="electricMotor1" class="com.chiranth.ElectricMotor1"/>
        <bean id="electricMotor2" class="com.chiranth.ElectricMotor2"/>
    
        <bean id="modelX" class="com.chiranth.TeslaModelX" autowire="constructor"/>
    </beans>
    

    Test.java

    package com.chiranth;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    public class Test 
    {
        public static void main(String[] args) 
        {
            ApplicationContext context= new ClassPathXmlApplicationContext("Spring.xml");
            TeslaModelX modelX=(TeslaModelX)context.getBean("modelX");
            modelX.goForward();
        }
    }
    

    OUTPUT:

    Motor 1 Started.
    Motor 2 Started.
    Going Forward.
    
    0 讨论(0)
提交回复
热议问题