春季限定符和属性占位符

2022-09-01 13:56:23

有谁知道我是否应该能够在限定符中使用属性占位符作为表达式?我似乎无法做到这一点。

我正在使用弹簧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
service.class=serviceB

答案 1

这有效。如果只使用默认的 spring bean 名称,则可以省略服务名称。服务 A 与服务 A 等

@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

此解决方案在没有 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);
    }
}

其他说明:

  • 仅用于将自动连接的字段。对于服务,要指定 Bean 名称,请使用 。@Qualifier@Service
  • 如果你想要标准的bean名称,你不需要使用特定的名称。例如,ServiceA 的标准 Bean 名称是(不是 - 请参阅大首字母),因此冗余 (就足够了)。@ServiceserviceAServiceA@Service("serviceA")@Service
  • 我基于这个答案:JavaConfig中的Spring Bean AliasAppConfig
  • 此解决方案优于此 Spring 限定符和属性占位符,因为您不需要 XML。
  • 已在 Spring Boot 1.5.7 上进行测试。

推荐