有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

JavaSpring限定符和属性占位符

有人知道我是否应该能够在限定符中使用属性占位符作为表达式吗?我好像没法让它工作

我正在使用Spring3.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

共 (5) 个答案

  1. # 1 楼答案

    我冒昧地猜测答案是否定的,只是基于几个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是一个非常一致的框架)

    Spring3.1有一个新的ProfileBean特性,它似乎可以完成一些您正在尝试做的事情。以下是对此的一篇评论:

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

  2. # 2 楼答案

    这很有效。如果只使用默认的Springbean名称,则可以省略服务名称。服务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
    
  3. # 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就足够了)
    • 我基于这个答案:Spring Bean Alias in JavaConfig
    • 这个解决方案比这个Spring Qualifier and property placeholder好,因为您不需要XML
    • 在弹簧靴1.5.7上测试
  4. # 4 楼答案

    作为工作区,您可以根据配置中的名称设置所需的Spring服务实现。财产

    @Controller
    public class MyController {
      //add a String which will hold the name of the service to implement
      @Value("${service.class}")
      private String serviceToImplement;
    
      Service service;
    
      // now autowire spring service bean based on int name using setter
      @Autowired
      public void setService(ApplicationContext context) {
        service = (Service) context.getBean(serviceToImplement);
       }
    }
    
    @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()");
       } 
    }
    

    配置。性质

    service.class=serviceB
    
  5. # 5 楼答案

    也许可以试一试:

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