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:

    

config.properties:

 config.properties service.class=serviceB 

这很有效。 如果只使用默认的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:

      

道具:

 service.class=ServiceB 

我冒昧地猜测答案是否定的,只是基于几个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

其中没有提到表达方式。 显然不是一个明确的答案(但spring在文档上通常非常好)。 此外,如果@Qualifier注释支持表达式,我希望它们的工作方式与@Value注释相同(仅基于spring是一个非常一致的框架)。

Spring 3.1具有新的配置文件beanfunction,看起来它可以完成类似于你想要做的事情。 这是一个写的:

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

此解决方案无需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用于将自动assembly的字段。 对于服务,要指定bean名称,请使用@Service
  • 如果您想要标准bean名称,则不需要将@Service与specyify名称一起使用。 例如,ServiceA的标准bean名称是serviceA (不是ServiceA – 请参阅大写的第一个字母),因此@Service("serviceA")冗余的( @Service就足够了)。
  • 我基于这个答案的AppConfig : JavaConfig中的Spring Bean Alias 。
  • 此解决方案优于此Spring限定符和属性占位符 ,因为您不需要XML。
  • 在Spring Boot 1.5.7上测试过。

也许给这个旋转:

 @Controller public class MyController { private String serviceId; @Value("${serviceId}") public void setServiceId(String serviceId) { this.serviceId = serviceId; } @Autowired @Qualifier(serviceId) Service service; }