EdeeShop · Implementace

Přetěžování core služeb

Upraveno

Mechanismus @ConditionalOnNoCustomService umožňuje v klientském projektu nahradit výchozí core beanu vlastní implementací. Core beana se při přetížení vůbec nezaregistruje — v kontextu vznikne vždy jen jedna instance. Odpadá tak nutnost přetěžovat celou @Configuration třídu pomocí configurationOverride kvůli jedné službě.

Použití v core modulu

Služba, která má být rozšiřitelná, se v @Configuration třídě označí anotací @ConditionalOnNoCustomService:

java
@ConditionalOnNoCustomService@Beanpublic AbstractCompanyService companyService(CoreDependency dao) {    return new DefaultCompanyService(dao);}

Anotace automaticky použije název metody (companyService) jako klíč. Pokud je potřeba specifikovat jiný klíč, lze ho předat jako parametr:

java
@ConditionalOnNoCustomService("myCustomKey")@Beanpublic AbstractCompanyService companyService(CoreDependency dao) {    return new DefaultCompanyService(dao);}

Použití v klientském projektu

1. Vytvoření properties souboru

V klientském projektu vytvořte soubor src/main/resources/META-INF/edee-custom-services.properties a přidejte název přetěžované beany jako klíč. Jako hodnotu zapište plně kvalifikovaný název nové třídy (implementace vyhodnocuje pouze existenci klíče, ale hodnota slouží pro přehlednost a případné budoucí využití):

properties
# Vypne načtení core beany 'companyService'companyService=com.fg.client.CustomCompanyService

2. Definice vlastní beany

V projektu nadefinujte vlastní beanu (klidně se stejným názvem), do které si přes konstruktor nainjektujete projektové závislosti:

java
@Configurationpublic class ProjectCompanyConfig {
    @Bean    public AbstractCompanyService companyService(            ProjectSpecificDependency projectDep,            CoreDependency dao    ) {        return new ProjectCompanyService(projectDep, dao);    }}

Protože core beana nebyla díky property souboru vůbec zaregistrována, nedojde k porušení allowBeanDefinitionOverriding=false.

Testování

V JUnit testech stačí na classpath umístit testovací verzi properties souboru:

kód
src/test/resources/META-INF/edee-custom-services.properties

Výhody oproti @Primary

Aspekt@Primary@ConditionalOnNoCustomService
Počet instancí v kontextuObě (core + klientská)Pouze klientská
Dopad na start a paměťZbytečná inicializace core beanyCore beana se vůbec nevytváří
Ochrana proti kolizi jmenVyžaduje jiné jméno beanySpolehlivě obchází overriding
Složitost pro vývojáře@Primary + správné pojmenováníJeden řádek v properties souboru

Klíčové třídy

  • com.fg.cps.eshop.cps.config.spring.annotation.ConditionalOnNoCustomService — anotace pro označení výchozích bean metod
  • com.fg.cps.eshop.cps.config.spring.annotation.NoCustomServiceCondition — evaluátor podmínky