2015-06-07 7 views
6

Mam Map<String, String> i chciałbym powiedzieć Spring, aby użył tego przy tworzeniu fasoli i rozwiązywaniu obiektów zastępczych. Jaki jest najłatwiejszy sposób na zrobienie tego? Oto przykład:Jak mogę nakazać Springowi użycie mapy Java do rozwiązania zastępczego obiektu?

@Component 
public class MyClass { 
    private String myValue; 

    @Autowired 
    public MyClass(@Value("${key.in.map}") String myValue) { 
     this.myValue = myValue; 
    } 

    public String getMyValue() { 
     return myValue; 
    } 
} 

public static void main(String[] args) { 
    Map<String, String> propertyMap = new HashMap<>(); 
    propertyMap.put("key.in.map", "value.in.map"); 
    ApplicationContext ctx = ...; 
    // Do something??? 
    ctx.getBean(MyClass.class).getMyValue(); // Should return "value.in.map" 
} 
+0

Czy można wstrzyknąć klucz mapy na właściwość fasoli sprężystej, która jest drugorzędna. Przede wszystkim robisz 'nową HashMap <>();'. Kontekst wiosny nie będzie w stanie rozpoznać tego komponentu bean. Będziesz musiał uzyskać ten komponent również z kontekstu Spring, wykonując coś w stylu 'ctx.getBean (java.util.HashMap.class)'. Następnie [here] (http://stackoverflow.com/questions/27285202/inject-map-of-beans-using-spring-from-properties-file) jest przykładem, gdzie użytkownik mógł uzyskać dostęp do właściwości za pomocą '

+0

@ Amit.rk3 Dzięki za wejście Amrit. Nie jestem pewien, czy w pełni rozumiesz ustawienie. Nie jestem zainteresowany robieniem 'ctx.getBean (HashMap.class)'.Mam odwzorowanie ciągu znaków na ciąg i chciałbym powiedzieć Springowi, aby używał tej mapy do rozwiązywania symboli zastępczych właściwości. – Max

+0

OK. W swoim pytaniu wspomniałeś o mapie java. To mnie zdezorientowało :). W każdym razie, aby po prostu mapować ciągi z listy właściwości, możesz zachować wpisy w pliku .properties i załadować je. Istnieje wiele odpowiedzi na to. –

Odpowiedz

3

Wiosna zapewnia MapPropertySource które można zarejestrować (trzeba mieć ConfigurableEnvironment które dostarczają większość ApplicationContext implementacje twoi ApplicationContext „s Environment).

Te zarejestrowane wartości PropertySource są używane przez przeliczniki (w kolejności) do znalezienia wartości dla nazw zastępczych.

Oto pełna przykład:

@Configuration 
@ComponentScan 
public class Example { 

    @Bean 
    public static PropertySourcesPlaceholderConfigurer configurer() { 
     PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer(); 
     // can also add it here 
     //configurer.setPropertySources(propertySources); 
     return configurer; 
    } 

    public static void main(String[] args) { 
     Map<String, Object> propertyMap = new HashMap<>(); 
     propertyMap.put("key.in.map", "value.in.map"); 
     AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); 
     MapPropertySource propertySource = new MapPropertySource("map-source", propertyMap); 
     ctx.getEnvironment().getPropertySources().addLast(propertySource); 
     ctx.register(Example.class); 
     ctx.refresh(); 

     MyClass instance = ctx.getBean(MyClass.class); 
     System.out.println(instance.getMyValue()); 
    } 
} 

@Component 
class MyClass { 
    private String myValue; 
    @Autowired 
    public MyClass(@Value("${key.in.map}") String myValue) { 
     this.myValue = myValue; 
    } 
    public String getMyValue() { 
     return myValue; 
    } 
} 
+0

Dzięki za odpowiedź. Czy to zachowanie różni się od korzystania z pliku właściwości bezpośrednio? Na przykład, co się stanie, jeśli spróbujesz wykonać '@Value (" my.int.key ") w myValue'? – Max

+0

@Max Po zarejestrowaniu pliku właściwości, za kulisami, Spring rejestruje 'PropertiesPropertySource'. Są one rejestrowane w dowolnej kolejności. 'PropertySourcesPlaceholderConfigurer' iteruje przez źródła, próbując znaleźć daną właściwość, np. 'my.int.key'. Jeśli tak, to go używa. Jeśli nie, działa dalej, dopóki nie pozostanie więcej źródeł. W tym momencie rzuci wyjątek. –

+0

Ale plik właściwości jest odwzorowaniem ciągu znaków -> ciąg, ponieważ w pliku nie ma informacji o typie. Typ MapPropertySource to mapa ciągu znaków -> obiekt. Przykładem 'int' było pytanie, czy muszę zająć się konwertowaniem typów' int'? – Max

-1

Udało mi się osiągnąć podobną funkcjonalność, chociaż może nie to, czego szukasz.

Oto mój kod:

application.properties

key.in.map=value.in.map 

beans.xml

http://www.springframework.org/schema/ partia http://www.springframework.org/schema/batch/spring-batch-2.1.xsd http://www.springframework.org/schema/jdbchttp://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsd „>

<context:component-scan base-package="com.chatar" /> 
</beans:beans> 

Config.java

package com.chatar.batch; 

import org.springframework.beans.factory.config.PropertiesFactoryBean; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.core.io.ClassPathResource; 

@Configuration 
public class Config { 

    @Bean(name = "mapper") 
    public PropertiesFactoryBean mapper() { 
     PropertiesFactoryBean bean = new PropertiesFactoryBean(); 
     bean.setLocation(new ClassPathResource("META-INF/spring/application.properties")); 
     return bean; 
    } 
} 

MyClazz.java

package com.chatar.batch; 

import java.util.Map; 

import org.springframework.beans.factory.annotation.Value; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.support.ClassPathXmlApplicationContext; 
import org.springframework.stereotype.Component; 

@Component 
public class MyClazz { 
    @Value("#{mapper}") 
    private Map<String, String> props; 

    public Map<String, String> getProps() { 
     return props; 
    } 

    public static void main(String[] args) { 
     ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); 

     System.out.println("Value:: " + context.getBean(MyClazz.class).getProps().get("key.in.map")); // Should return 
    } 
} 

wyjściowa: Wartość :: value.in.map

+0

Dzięki za długą i szczegółową odpowiedź. Nie było to dokładnie to, czego szukałem, ale dało mi to kilka dobrych pomysłów. – Max

0

Oto rozwiązanie I skończyło się. Konwertuję mapę na plik właściwości.

Map<String, String> propertyMap = ...; 
Properties properties = new Properties(); 
properties.putAll(propertyMap); 

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); 
ConfigurableBeanFactory beanFactory = ctx.getBeanFactory(); 
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer(); 
propertySourcesPlaceholderConfigurer.setProperties(properties); 
beanFactory.registerSingleton(PropertySourcesPlaceholderConfigurer.class.getSimpleName(), 
        propertySourcesPlaceholderConfigurer); 
+0

To wystarczy! :). –

Powiązane problemy