मेरे पास एक वर्ग है जिसमें Daemon प्रकार की वस्तुओं की एक सूची है।

class Xyz {    
    List<Daemon> daemons;
}

मेरा वसंत विन्यास इस तरह दिखता है।

<bean id="xyz" class="package1.Xyz">
   <property name="daemons" ref="daemonsList">
</bean>

<bean id="daemon1" class="package1.DaemonImpl1"/>
<bean id="daemon2" class="package1.DaemonImpl2"/>

<bean id="daemonsList" class="java.util.ArrayList">
        <constructor-arg>
            <list>
                <ref bean="daemon1" />      
                <ref bean="daemon2" />
            </list>
        </constructor-arg>
</bean>

अब सूची में प्रत्येक डेमॉन कार्यान्वयन को स्पष्ट रूप से तार-तार करने के बजाय, क्या सूची में स्वचालित रूप से Daemon प्रकार के सभी बीन्स को ऑटोवायर करना संभव है। जिस समस्या को मैं हल करने का प्रयास कर रहा हूं, वह है, यदि कोई Daemon वर्ग के नए कार्यान्वयन का बीन बनाता है और उसे सूची में तार करना भूल जाता है।

मैंने इस प्रश्न को स्टैक ओवरफ्लो पर कहीं देखा है लेकिन इसे फिर से नहीं ढूंढ पा रहा हूं। इसके लिए खेद है।

83
RandomQuestion 16 सितंबर 2011, 18:36
2
देखें देता है nosuchbeandefinitionexception"> stackoverflow.com/questions/1363310/…
 – 
skaffman
16 सितंबर 2011, 19:06
धन्यवाद स्काफमेन। मैं यहां शामिल अवधारणा को समझने की कोशिश करूंगा।
 – 
RandomQuestion
16 सितंबर 2011, 19:21

2 जवाब

सबसे बढ़िया उत्तर

इसे इस तरह काम करना चाहिए (अपने एक्सएमएल से ऐरेलिस्ट बीन को हटा दें):

public Class Xyz {    

    private List<Daemon> daemons;

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

}

मुझे नहीं लगता कि एक्सएमएल में ऐसा करने का कोई तरीका है।


देखो: 3.9.2. @Autowired और @Inject:

किसी फ़ील्ड या विधि में एनोटेशन जोड़कर एप्लिकेशनकॉन्टेक्स्ट से किसी विशेष प्रकार के सभी बीन्स प्रदान करना भी संभव है जो उस प्रकार की सरणी की अपेक्षा करता है:

public class MovieRecommender {

  @Autowired
  private MovieCatalog[] movieCatalogs;

  // ...
}

टाइप किए गए संग्रहों के लिए भी यही लागू होता है:

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, स्प्रिंग 4.x तक, इन सूचियों को @Ordered तंत्र का उपयोग करके स्वचालित रूप से आदेश दिया जा सकता है।

85
Mukund Jalan 2 अप्रैल 2019, 15:49
7
धन्यवाद शॉन। इसने काम कर दिया। मैंने सोचा, @Autowired अंकन को List<Daemons> daemons में जोड़ने से java.util.List प्रकार की फलियों की वसंत खोज हो जाएगी। यह आश्चर्यजनक है, यह कैसे सूची में वस्तुओं के प्रकार का पता लगाता है और उन्हें सूची में तार देता है और अंत में तारों की सूची मुख्य वस्तु में।
 – 
RandomQuestion
16 सितंबर 2011, 19:12
1
@अल। कोई परेशानी नहीं। मैं खुद इस सुविधा का बहुत उपयोग करता हूं
 – 
Sean Patrick Floyd
1 जुलाई 2015, 11:48
जब ऑटोवायरिंग "लिस्ट<डेमॉन> डेमॉन", स्प्रिंग को कैसे पता चलता है कि उसे डेमन प्रकार के बीन्स की तलाश करनी चाहिए, क्योंकि यह सामान्य प्रकार है और रनटाइम पर उपलब्ध नहीं होगा?
 – 
elyor
9 अक्टूबर 2017, 19:20
1
यह बिल्कुल सही नहीं है। ऑब्जेक्ट टाइप इरेज़र के अधीन हैं, फ़ील्ड और विधियाँ नहीं हैं। प्रतिबिंब आपको Method.getGenericParameterTypes()
 – 
Sean Patrick Floyd
9 अक्टूबर 2017, 19:25

ठीक है, इसे दो तरीकों से प्राप्त किया जा सकता है जैसा कि स्प्रिंग दस्तावेज़ीकरण

नीचे दस्तावेज़ीकरण से अंश है।

बायटाइप या कंस्ट्रक्टर ऑटोवायरिंग मोड के साथ, आप सरणियों और टाइप किए गए संग्रहों को तार कर सकते हैं।

<मजबूत>1. autowire="byType"

यदि एक्सएमएल में परिभाषित बीन का प्रकार सूची के प्रकार से मेल खाता है तो "बायटाइप" का उपयोग करके ऑटोवायरिंग प्राप्त की जा सकती है।

उदाहरण:

मोटर.जावा

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

इलेक्ट्रिकमोटर1.जावा

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

इलेक्ट्रिकमोटर2.जावा

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

टेस्लामॉडलX.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.");
    }
}

स्प्रिंग.एक्सएमएल

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

टेस्ट.जावा

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

आउटपुट:

Motor 1 Started.
Motor 2 Started.
Going Forward.

<मजबूत>2. autowire="constructor"

"कन्स्ट्रक्टर" का उपयोग करके ऑटोवायरिंग प्राप्त की जा सकती है यदि xml में परिभाषित बीन का प्रकार कंस्ट्रक्टर में तर्क के प्रकार से मेल खाता हो।

उदाहरण:

उपरोक्त Motor.java , ElectricMotor1.java और ElectricMotor2.java को ध्यान में रखते हुए।

टेस्लामॉडलX.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.");
    }
}

स्प्रिंग.एक्सएमएल

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

टेस्ट.जावा

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

आउटपुट:

Motor 1 Started.
Motor 2 Started.
Going Forward.
4
chiranth 18 जुलाई 2019, 19:36
जवाब के लिए धन्यवाद। किसी भी समाधान के लिए प्रश्न: क्या यह काम करेगा यदि "electricMotor1" और "electricMotor2" ... "electricMotorN" को एक ही spring.xml फ़ाइल में परिभाषित नहीं किया गया है, लेकिन एक ही ApplicationContext कंटेनर साझा करें?
 – 
Liang
7 जून 2020, 01:31