2011-10-18 13 views
21

क्या किसी को पता है कि क्या मुझे प्रॉपर्टी प्लेसहोल्डर को क्वालीफायर में अभिव्यक्ति के रूप में उपयोग करने में सक्षम होना चाहिए? मुझे यह काम नहीं मिल रहा है।स्प्रिंग क्वालीफायर और प्रॉपर्टी प्लेसहोल्डर

मैं वसंत 3.0.4 का उपयोग कर रहा हूं।

@Controller 
public class MyController { 
    @Autowired 
    @Qualifier("${service.class}") 
    Service service; 
} 

@Service 
@Qualifier("ServiceA") 
ServiceA implements Service { 
    public void print() { 
     System.out.println("printing ServiceA.print()"); 
    } 
} 

@Service 
@Qualifier("ServiceB") 
ServiceB implements Service { 
    public void print() { 
     System.out.println("printing ServiceB.print()"); 
    } 
} 

एक्सएमएल:

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
     <property name="location" value="file:/etc/config.properties"/> 
</bean> 

config.properties:

config.properties 
service.class=serviceB 
+1

क्या आप वसंत 3 का उपयोग कर रहे हैं? – Kevin

+0

हां। सवाल अपडेट किया गया। – Langali

+0

गुण फ़ाइल में और '@ क्वालीफायर' के साथ ऐसा करने का क्या मतलब होगा जब आप बस एक्सएमएल में बीन को वायर करने के तरीके को चुन सकते हैं? –

उत्तर

4

मैं जवाब का अनुमान लगाना उद्यम होगा बस कुछ ही जावाडोक पन्नों में लिखने अप के आधार पर नहीं है,। उदाहरण के लिए, @Value के लिए दस्तावेज़ देख सकेंगे:

http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/beans/factory/annotation/Value.html

सूचना वे एनोटेशन में भाव का उपयोग करने का विशेष उल्लेख करते हैं। तुलना के लिए, @Qualifier के लिये दस्तावेज:

http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/beans/factory/annotation/Qualifier.html

कौन सा भाव का कोई जिक्र नहीं किया जाता है। स्पष्ट रूप से एक निश्चित उत्तर नहीं है (लेकिन वसंत आमतौर पर प्रलेखन पर बहुत अच्छा है)। इसके अलावा, अगर एनोटेशन में अभिव्यक्तियों का समर्थन किया गया तो मुझे उम्मीद है कि वे @Value एनोटेशन (बस वसंत पर आधारित एक बहुत ही स्थिर ढांचे के समान) काम करेंगे।

स्प्रिंग 3.1 में नई प्रोफ़ाइल बीन सुविधा है, जो ऐसा लगता है जैसे आप ऐसा करने की कोशिश कर रहे हैं। यहाँ है कि के लिए एक राइट हो रहा है:

http://blog.springsource.com/2011/02/14/spring-3-1-m1-introducing-profile/

-3

हो सकता है कि यह एक बार आज़माएंगे:

@Controller 
public class MyController { 

    private String serviceId; 

    @Value("${serviceId}") 
    public void setServiceId(String serviceId) { 
     this.serviceId = serviceId; 
    } 

    @Autowired 
    @Qualifier(serviceId) 
    Service service; 
} 
+5

एनोटेशन मान स्थिरांक होना चाहिए, इसलिए यह – JodaStephen

+1

@Aaron http://docs.oracle.com/javase/1.5.0/docs/guide/language/annotations.html एनोटेशन में एक एट-साइन (@) एक एनोटेशन प्रकार और तत्व-मूल्य जोड़े की एक संश्लेषित सूची के बाद। मान संकलन-समय स्थिरांक होना चाहिए, इसलिए एक उदाहरण स्ट्रिंग के साथ कामकाज संकलन त्रुटि का कोर्स नहीं करेगा .... – beagle

37

यह काम करता है। यदि आप केवल डिफ़ॉल्ट वसंत बीन नाम का उपयोग करते हैं तो आप सेवा नाम छोड़ सकते हैं। serviceà serviceà बनाम, आदि

@Controller 
class MyController { 
@Autowired(required=false) 
@Qualifier("Service") 
Service service; 

public static void main(String[] args) { 
    ApplicationContext context = new ClassPathXmlApplicationContext("app-ctx.xml", MyController.class); 
    for(String s:context.getBeanDefinitionNames()){ 
     System.out.println(s); 
     for(String t:context.getAliases(s)){ 
      System.out.println("\t" + t); 
     } 
    } 
    context.getBean(MyController.class).service.print(); 
    } 
} 

public interface Service { 
    void print(); 
} 

@Service(value="ServiceA") 
public class ServiceA implements example.Service { 
    public void print() { 
     System.out.println("printing ServiceA.print()"); 
    } 
} 

@Service(value="ServiceB") 
public class ServiceB implements example.Service { 
    public void print() { 
     System.out.println("printing ServiceB.print()"); 
    } 
} 

एक्सएमएल:

<beans> 
    <alias name="${service.class}" alias="Service"/> 
    <context:property-placeholder location="example/app.properties"/> 
    <context:component-scan base-package="example"/> 
<beans> 

प्रॉप्स:

service.class=ServiceB 
+2

डुनो क्यों इसे स्वीकार नहीं किया गया है। यह निश्चित रूप से ओपी चाहता था करने के लिए सबसे अच्छा तरीका है। +1 – lost

+0

अच्छा समाधान ... –

+0

क्या कोई कारण है कि आपने '@ Autowired' एनोटेशन पर' आवश्यक = "झूठी" कहा? –

3

यह समाधान एक्सएमएल के बिना और गुण फ़ाइल के साथ काम करता है।

तुम्हारा कक्षाओं में सुधार:

MyController.java:

@Controller 
public class MyController { 
    @Autowired 
    public MyController(@Qualifier("MyServiceAlias") MyService myService) { 
     myService.print(); 
    } 
} 

ServiceA.java:

@Service("serviceA") 
public class ServiceA implements MyService { 
    @Override 
    public void print() { 
     System.out.println("printing ServiceA.print()"); 
    } 
} 

ServiceB.java:

@Service("serviceB") 
public class ServiceB implements MyService { 
    @Override 
    public void print() { 
     System.out.println("printing ServiceB.print()"); 
    } 
} 

application.properties (यहां आप बदल सकते हैं कि किस वर्ग लोड किया जाएगा):

service.class=serviceA 

और महत्वपूर्ण विन्यास फाइल AppConfig.java:

@Configuration 
public class AppConfig { 

    @Autowired 
    private ApplicationContext context; 

    @Bean 
    public MyService MyServiceAlias(@Value("${service.class}") String qualifier) { 
     return (MyService) context.getBean(qualifier); 
    } 
} 

अतिरिक्त स्पष्टीकरण:

  • उपयोग @Qualifier केवल के लिए क्षेत्र जो स्वचालित हो जाएगा। सेवाओं के लिए, बीन नाम निर्दिष्ट करने के लिए, @Service का उपयोग करें।
  • यदि आप मानक बीन नाम चाहते हैं तो आपको specyify नाम के साथ @Service का उपयोग करने की आवश्यकता नहीं है। उदाहरण के लिए, सेवा ए के लिए मानक बीन नाम serviceA है (ServiceA नहीं - बड़ा पहला अक्षर देखें), इसलिए @Service("serviceA") अनावश्यक (@Service पर्याप्त है)।
  • मैं इस उत्तर पर AppConfig आधारित हूं: Spring Bean Alias in JavaConfig
  • यह समाधान Spring Qualifier and property placeholder से बेहतर है, क्योंकि आपको XML की आवश्यकता नहीं है।
  • स्प्रिंग बूट 1.5.7 पर परीक्षण किया गया।
+0

ग्रेट यह शानदार काम करता है – Balaji

संबंधित मुद्दे