Spring Framework
Implementing ImportSelector to select configuration classes.
package com.logicbig.example;import org.springframework.context.annotation.ImportSelector;import org.springframework.core.type.AnnotationMetadata;public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { String prop = System.getProperty("myProp"); if ("someValue".equals(prop)) { return new String[]{MyConfig1.class.getName()}; } else { return new String[]{MyConfig2.class.getName()}; } }}
package com.logicbig.example;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class MyConfig1 { @Bean AppBean appBean() { return new AppBean("from config 1"); }}
package com.logicbig.example;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class MyConfig2 { @Bean AppBean appBean() { return new AppBean("from config 2"); }}
package com.logicbig.example;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;@Configuration@Import(MyImportSelector.class)public class MainConfig { @Bean ClientBean clientBean() { return new ClientBean(); }}
package com.logicbig.example;public class AppBean { private String message; public AppBean(String message) { this.message = message; } public String getMessage() { return message; }}
package com.logicbig.example;import org.springframework.beans.factory.annotation.Autowired;public class ClientBean { @Autowired private AppBean appBean; public void doSomething() { System.out.println(appBean.getMessage()); }}
package com.logicbig.example;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class ImportSelectorExample { public static void main(String[] args) { System.setProperty("myProp", "someValue"); ApplicationContext context = new AnnotationConfigApplicationContext( MainConfig.class); ClientBean bean = context.getBean(ClientBean.class); bean.doSomething(); }}
from config 1
Implementing ImportSelector and using a custom annotation to select configuration classes.
package com.logicbig.example;import org.springframework.context.annotation.ImportSelector;import org.springframework.core.annotation.AnnotationAttributes;import org.springframework.core.type.AnnotationMetadata;public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { AnnotationAttributes attributes = AnnotationAttributes.fromMap( importingClassMetadata.getAnnotationAttributes( EnableSomeModule.class.getName(), false)); String value = attributes.getString("value"); if ("someValue".equals(value)) { return new String[]{MyConfig1.class.getName()}; } else { return new String[]{MyConfig2.class.getName()}; } }}
package com.logicbig.example;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configuration@EnableSomeModule("someValue")public class MainConfig { @Bean ClientBean clientBean() { return new ClientBean(); }}
package com.logicbig.example;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class ImportSelectorWithAnnotationExample { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext( MainConfig.class); ClientBean bean = context.getBean(ClientBean.class); bean.doSomething(); }}
Overriding ImportSelector#getExclusionFilter() to filter selected configuration classes.
package com.logicbig.example;import org.springframework.context.annotation.ImportSelector;import org.springframework.core.type.AnnotationMetadata;import java.util.function.Predicate;public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { String prop = System.getProperty("myProp"); if ("someValue".equals(prop)) { return new String[]{MyConfig1.class.getName(), MyConfig3.class.getName()}; } else { return new String[]{MyConfig2.class.getName()}; } } @Override public Predicate<String> getExclusionFilter() { return configClass -> { if (configClass.equals(MyConfig3.class.getName())) { return true; } return false; }; }}
package com.logicbig.example;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class MyConfig1 { @Bean AppBean appBean1() { return new AppBean("from config 1"); }}
package com.logicbig.example;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class MyConfig2 { @Bean AppBean appBean2() { return new AppBean("from config 2"); }}
package com.logicbig.example;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class MyConfig3 { @Bean AppBean appBean3() { return new AppBean("from config 3"); }}
package com.logicbig.example;import org.springframework.beans.factory.annotation.Autowired;import java.util.List;public class ClientBean { @Autowired private List<AppBean> appBeanList; public void doSomething() { for (AppBean appBean : appBeanList) { System.out.println(appBean.getMessage()); } }}
package com.logicbig.example;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class ImportSelectorExclusionFilterMain { public static void main(String[] args) { System.setProperty("myProp", "someValue"); ApplicationContext context = new AnnotationConfigApplicationContext( MainConfig.class); ClientBean bean = context.getBean(ClientBean.class); bean.doSomething(); }}
This example shows that main configuration for the same beans overrides the imported configuration
package com.logicbig.example;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;@Configuration@Import(MyImportSelector.class)public class MainConfig { @Bean ClientBean clientBean() { return new ClientBean(); } @Bean AppBean appBean() { return new AppBean("from main config "); }}
package com.logicbig.example;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.*;import org.springframework.core.type.AnnotationMetadata;public class ImportSelectorPrecedenceDemo { public static void main(String[] args) { System.setProperty("myProp", "someValue"); ApplicationContext context = new AnnotationConfigApplicationContext( MainConfig.class); ClientBean bean = context.getBean(ClientBean.class); bean.doSomething(); }}
from main config
Configuration selection with @ComponentScan:
package com.logicbig.example;import org.springframework.context.annotation.ImportSelector;import org.springframework.core.annotation.AnnotationAttributes;import org.springframework.core.type.AnnotationMetadata;public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { String prop = System.getProperty("myProp"); if ("someValue".equals(prop)) { return new String[]{MyConfig2.class.getName()}; } else { return new String[]{MyConfig1.class.getName()}; } }}
package com.logicbig.example;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;@Configuration@ComponentScan("com.logicbig.example.service1")public class MyConfig1 {}
package com.logicbig.example;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;@Configuration@ComponentScan("com.logicbig.example.service2")public class MyConfig2 {}
package com.logicbig.example;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;@Configuration@ComponentScan("com.logicbig.example.main")@Import(MyImportSelector.class)public class MainConfig {}
package com.logicbig.example;public interface AppService { void doSomething();}
package com.logicbig.example.service1;import com.logicbig.example.AppService;import org.springframework.stereotype.Service;@Servicepublic class AppService1 implements AppService { @Override public void doSomething() { System.out.println("In AppService1"); }}
package com.logicbig.example.service2;import com.logicbig.example.AppService;import org.springframework.stereotype.Service;@Servicepublic class AppService2 implements AppService { public void doSomething() { System.out.println("in bean 2"); }}
package com.logicbig.example.main;import com.logicbig.example.AppService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;@Componentpublic class ClientBean { @Autowired private AppService appBean; public void doSomething() { appBean.doSomething(); }}
package com.logicbig.example;import com.logicbig.example.main.ClientBean;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class ImportSelectorWithComponentScanExample { public static void main(String[] args) { System.setProperty("myProp", "someValue"); ApplicationContext context = new AnnotationConfigApplicationContext( MainConfig.class); ClientBean bean = context.getBean(ClientBean.class); bean.doSomething(); }}
in bean 2