Spring限定符和属性占位符

Lan*_*ali 24 java spring dependency-injection

有谁知道我是否应该使用属性占位符作为限定符中的表达式?我似乎无法让这个工作.

我使用的是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()");
   } 
}
Run Code Online (Sandbox Code Playgroud)

XML:

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="file:/etc/config.properties"/>
</bean>
Run Code Online (Sandbox Code Playgroud)

config.properties:

config.properties
service.class=serviceB
Run Code Online (Sandbox Code Playgroud)

小智 40

这有效.如果只使用默认的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()");
    } 
}
Run Code Online (Sandbox Code Playgroud)

XML:

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

道具:

service.class=ServiceB
Run Code Online (Sandbox Code Playgroud)

  • Dunno为什么没有被接受.这绝对是做OP所需要的最好的方式.+1 (2认同)

mkc*_*zyk 11

此解决方案无需XML和属性文件即可运行.

你的课程改进了:

MyController.java:

@Controller
public class MyController {
    @Autowired
    public MyController(@Qualifier("MyServiceAlias") MyService myService) {
        myService.print();
    }
}
Run Code Online (Sandbox Code Playgroud)

ServiceA.java:

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

ServiceB.java:

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

application.properties (这里你可以改变要加载的类):

service.class=serviceA
Run Code Online (Sandbox Code Playgroud)

而重要的配置文件AppConfig.java:

@Configuration
public class AppConfig {

    @Autowired
    private ApplicationContext context;

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

补充说明:

  • 使用@Qualifier仅用于现场将被自动装配.对于服务,要指定bean名称,请使用@Service.
  • 如果您想要标准bean名称,则不需要使用@Servicespecyify名称.例如,ServiceA的标准bean名称是serviceA(不是ServiceA- 见大第一个字母),所以@Service("serviceA")多余(@Service足够).
  • 我基于AppConfig这个答案:JavaConfig中的Spring Bean Alias.
  • 此解决方案优于此Spring限定符和属性占位符,因为您不需要XML.
  • 在Spring Boot 1.5.7上测试过.


Kev*_*vin 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

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

Spring 3.1 具有新的配置文件 bean 功能,这似乎可以完成您想要做的事情。这是为此写的:

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