Jak zrobić warunkowe automatyczne okablowanie wiosną?

Czy ktoś próbował automatycznie przełożyć różne fasolki na fasolkę wiosenną w zależności od warunku? Dla np. jeśli spełniony jest jakiś warunek, to klasa a, inaczej B? Widziałem w jednym z wyników wyszukiwania Google, że jest to możliwe za pomocą SpEL( Spring Expression Language), ale nie mogłem znaleźć działającego przykładu.

 51
Author: Luiggi Mendoza, 2013-10-07

1 answers

Istnieje wiele sposobów, aby to osiągnąć. Głównie zależy to od kondycji, którą chcesz wykonać.

Factory bean

Możesz zaimplementować simple factory bean, aby wykonać okablowanie warunkowe. Taka fabryczna fasola może zawierać złożoną logikę kondycjonowania:

public MyBeanFactoryBean implements FactoryBean<MyBean> {

    // Using app context instead of bean references so that the unused 
    // dependency can be left uninitialized if it is lazily initialized
    @Autowired
    private ApplicationContext applicationContext;

    public MyBean getObject() {
        MyBean myBean = new MyBean();
        if (true /* some condition */) {
            myBean.setDependency(applicationContext.getBean(DependencyX.class));
        } else {
            myBean.setDependency(applicationContext.getBean(DependencyY.class));
        }
        return myBean;
    }

    // Implementation of isSingleton => false and getObjectType

}

Może nieco lepszym podejściem jest użycie factory bean do utworzenia zależności bean W przypadku, gdy chcesz mieć tylko jedną taką fasolę w aplikacji kontekst:

public MyDependencyFactoryBean implements FactoryBean<MyDependency> {

    public MyDependency getObject() {
        if (true /* some condition */) {
            return new MyDependencyX();
        } else {
            return new MyDependencyY();
        }
    }

    // Implementation of isSingleton => false and getObjectType

}

SpEL

SpEL ma wiele możliwości. Najczęściej spotykane są właściwości systemu warunki oparte:
<bean class="com.example.MyBean">
    <property name="dependency" value="#{systemProperties['foo'] == 'bar' ? dependencyX : dependencyY}" />
</bean>

Property placeholder

Możesz mieć property placeholder rozwiązać swoje odniesienie bean. Nazwa zależności może być częścią konfiguracji aplikacji.

<bean class="com.example.MyBean">
    <property name="dependency" ref="${dependencyName}" />
</bean>

Profile sprężynowe

Zazwyczaj warunek, który chcesz ocenić oznacza, że cały zestaw fasoli powinien lub nie powinien być zarejestrowany. Wiosna profile mogą być używane do tego celu:

<!-- Default dependency which is referred by myBean -->
<bean id="dependency" class="com.example.DependencyX" />

<beans profile="myProfile">
    <!-- Override `dependency` definition if myProfile is active -->
    <bean id="dependency" class="com.example.DependencyY" />
</beans>

Inne metody mogą oznaczyć definicję bean jako lazy-init="true", ale definicja będzie nadal zarejestrowana w kontekście aplikacji (i utrudni ci życie, gdy używasz autowiringu bez kwalifikacji). Możesz również używać profili z @Component na podstawie fasoli za pomocą @Profile adnotacji.

Sprawdź ApplicationContextInitialier (lub ten przykład ), aby zobaczyć, jak można aktywować profile programowo(tj. na podstawie twój stan ).

Java config

Dlatego konfiguracja oparta na Javie jest tak popularna, jak możesz to zrobić:

@Bean
public MyBean myBean() {
    MyBean myBean = new MyBean();
    if (true /* some condition */) {
        myBean.setDependency(dependencyX());
    } else {
        myBean.setDependency(dependencyY());
    }
    return myBean;
}

Oczywiście można użyć mniej więcej wszystkich metod konfiguracji w config java, jak również (poprzez @Profile, @Value lub @Qualifier + @Autowired).

Post processor

Spring oferuje liczne punkty zaczepienia i SPIs, w których można uczestniczyć w cyklu życia kontekstu aplikacji. Ta sekcja wymaga nieco więcej wiedzy o wewnętrznym funkcjonowaniu Springa.

BeanFactoryPostProcessors potrafi czytać i alter Bean definitions(np. property placeholder ${} resolution jest implementowana w ten sposób).

BeanPostProcessors może przetwarzać instancje fasoli. Można sprawdzić świeżo utworzoną fasolę i pobawić się nią (np. w ten sposób zaimplementowane jest przetwarzanie adnotacji @Scheduled).

MergedBeanDefinitionPostProcessor jest rozszerzeniem Bean Post processor i może zmienić definicję bean tuż przed jej utworzeniem (przetwarzanie adnotacji jest zaimplementowane w ten sposób).


Aktualizacja październik 2015

  • Spring 4 dodał nową metodę jak zrobić warunkową rejestrację poprzez @Conditional adnotacja. To też warto sprawdzić.

  • Oczywiście istnieje wiele innych sposobów z samym sprężynowym butem za pośrednictwem jego @ConditionalOn*.

  • Zauważ również, że zarówno @Import, jak i @ComponentScan (oraz ich odpowiedniki XML) podlegają rozdzielczości właściwości(np. możesz użyć ${}).

 75
Author: Pavel Horal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-07 08:08:55