1. 程式人生 > >Spring注入Bean的幾種方式 @Import,ImportSelector,ImportBeanDefinitionRegistrar的詳解

Spring注入Bean的幾種方式 @Import,ImportSelector,ImportBeanDefinitionRegistrar的詳解

給容器中註冊元件;
   1,包掃描+元件標註註解(@Controller/@Service/@Repository/@Component)[自己寫的類]
   2,@Bean[匯入的第三方包裡面的元件]
   3,@Import[快速給容器中匯入一個元件]
             1)、@Import(要匯入到容器中的元件);容器中就會自動註冊這個元件,id預設是全類名
             2)、ImportSelector:返回需要匯入的元件的全類名陣列;
             3)、ImportBeanDefinitionRegistrar:手動註冊bean到容器中
@Import的使用:

public class Blue {}
public class Red {}

@Configuration
@Import({ Blue.class, Red.class })// @Import匯入元件,id預設是元件的全類名
public class MainConfig {

}

測試
@Test
public void testImport() {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(
				MainConfig.class);
		printBeans(applicationContext);
	}
private void printBeans(AnnotationConfigApplicationContext applicationContext) {
		String[] definitionNames = applicationContext.getBeanDefinitionNames();
		for (String name : definitionNames) {
			System.out.println(name);
		}
	}

結果:

com.example.demo.model.Blue
com.example.demo.model.Red

ImportSelector的使用:

//自定義邏輯返回需要匯入的元件
public class MyImportSelector implements ImportSelector {
	// 返回值,就是到匯入到容器中的元件全類名
	// AnnotationMetadata:當前標註@Import註解的類的所有註解資訊
	@Override
	public String[] selectImports(AnnotationMetadata importingClassMetadata) {
		// 方法不要返回null值
		return new String[] { Blue.class.getName(), Yellow.class.getName() };
	}
}


@Configuration
@Import({ MyImportSelector.class })
public class MainConfig {

}


@Test
public void testImport() {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(
				MainConfig.class);
		printBeans(applicationContext);
	}
private void printBeans(AnnotationConfigApplicationContext applicationContext) {
		String[] definitionNames = applicationContext.getBeanDefinitionNames();
		for (String name : definitionNames) {
			System.out.println(name);
		}
	}

結果:

com.example.demo.model.Blue
com.example.demo.model.Yellow

ImportBeanDefinitionRegistrar的使用:

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
	/**
	 * AnnotationMetadata:當前類的註解資訊
	 * BeanDefinitionRegistry:BeanDefinition註冊類;
	 * 		把所有需要新增到容器中的bean;呼叫
	 * 		BeanDefinitionRegistry.registerBeanDefinition手工註冊進來
	 */
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

		boolean definition = registry.containsBeanDefinition(Red.class.getName());
		boolean definition2 = registry.containsBeanDefinition(Blue.class.getName());
		if (definition && definition2) {
			// 指定Bean定義資訊;(Bean的型別,Bean。。。)
			RootBeanDefinition beanDefinition = new RootBeanDefinition(Yellow.class);
			// 註冊一個Bean,指定bean名
			registry.registerBeanDefinition(Yellow.class.getName(), beanDefinition);
		}
	}
}



@Configuration
@Import({ MyImportSelector.class, MyImportBeanDefinitionRegistrar.class })
public class MainConfig {

}

結果:

com.example.demo.model.Blue
com.example.demo.model.Red
com.example.demo.model.Yellow