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
的文档:
请注意,他们特别提到在注释中使用表达式。 为了比较,@ @Qualifier
的文档:
其中没有提到表达方式。 显然不是一个明确的答案(但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; }
- Java / Jersey – 使用ParamInjectionResolver创建自己的注入解析器 – 奇怪的行为
- Guice – 如何通过多个注入器/模块共享同一个Singleton实例
- 使用guice作为注入类的框架,正确的初始化方法?
- Spring应用程序的各个方面的dependency injection?
- 为什么Spring不支持直接字段dependency injection(自动assembly除外)?
- Spring:构造函数注入具有基于注释的配置的原始值(属性)
- 记录和dependency injection
- JSF – 会话范围的托管bean没有在会话反序列化上重新注入依赖项
- 如何以编程方式创建具有注入属性的bean定义?