2011-10-18 111 views
21

有誰知道我是否應該能夠在限定符中使用屬性佔位符作爲表達式?我似乎無法得到這個工作。Spring限定符和屬性佔位符

我使用的是spring 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()"); 
    } 
} 

XML:

<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

當你可以選擇如何在XML中連接bean時,在屬性文件中使用「@ Qualifier」做什麼? –

回答

4

我冒昧猜測答案是否定的,只是根據在少數的javadoc頁面寫窗口。例如,請參閱該文檔爲@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

這使得沒有提及的表達式。顯然不是一個明確的答案(但春天通常對文檔非常好)。另外,如果在@Qualifier註釋中支持表達式,我希望它們的工作方式與@Value註釋相同(只是基於spring是一個非常一致的框架)。

Spring 3.1具有新的配置文件bean功能,它看起來像它可以完成像你想要做的事情。下面是一個寫了起來:

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註解包含一個at-sign( @)後面跟着一個註釋類型和一個括號化的元素值對列表。值必須是編譯時常量因此,對於實例字符串的解決方法將無法正常工作編譯錯誤的過程.... – beagle

37

這工作。如果您只使用默認的Spring bean名稱,則可以忽略服務名稱。 serviceA VS ServiceA等

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

XML:

<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

不知道爲什麼這不被接受。這是決定OP最想做什麼的最好方式。 +1 – lost

+0

很好的解決方案... –

+0

是否有任何理由爲'@ Autowired'註釋添加'required =「false」'? –

3

此方法適用於沒有XML與屬性文件。

此致類改進:

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只爲該字段將被自動裝配。對於服務,要指定bean名稱,請使用@Service
  • 如果你想標準bean名稱,你不需要使用@Service specyify名稱。例如,ServiceA的標準bean名稱是serviceA(不是ServiceA - 請參閱大首字母),因此@Service("serviceA")冗餘(@Service就足夠了)。
  • 我基於AppConfig對此回答:Spring Bean Alias in JavaConfig
  • 此解決方案比此Spring Qualifier and property placeholder更好,因爲您不需要XML。
  • 測試Spring Boot 1.5.7。
+0

偉大的作品真棒 – Balaji