2011-10-18 112 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