Spring注入Bean的四種方式,看這一篇就夠了

Harrison__發表於2020-10-22

1.通過xml配置注入bean

<bean id="user" class="com.asong.User">
		<property name="name" value="asong"></property>
		<property name="age" value="19"></property>
</bean>

2.通過配置類和@Bean註解注入bean(@Configuration、@Bean)

@Configuration
public class Config {
	//給容器中註冊一個bean, 型別為返回值的型別, 
	@Bean("user")	//bean的id
	public User user(){
		return new Person("asong",19);
	}
}

可以和@Conditional連用,此時為條件注入,需要實現Spring提供的Condition介面

@Conditional({xxx.class,xx.class})

@Scope可以設定單例或多例,Spring預設為單例,引數可設定為以下四種

* prototype:多例項: IOC容器啟動的時候,IOC容器啟動並不會去呼叫方法建立物件, 而是每次獲取的時候才會呼叫方法建立物件
* singleton:單例項(預設):IOC容器啟動的時候會呼叫方法建立物件並放到IOC容器中,以後每次獲取的就是直接從容器中拿(大Map.get)的同一個bean
* request: 主要針對web應用, 遞交一次請求建立一個例項
* session:同一個session建立一個例項

@Lazy註解可以設定Bean懶載入,即使用時載入(Spring預設ioc容器建立時載入Bean)

3.通過配置類和@Import註解注入bean,預設id為類全名(包名+類名)

@Configuration
//引數為Bean的class,也可以為ImportSelector和ImportBeanDefinitionRegistrar的實現類class
@Import(value = { User.class,Dog.class})
public class Config {

    ...
}

@Import這裡的引數為class陣列,可以傳入Bean的class,也可以傳入ImportSelector和ImportBeanDefinitionRegistrar的實現類class

介面ImportSelector:Spring提供的一個介面,可以指定傳入的Bean,需要實現String[] selectImports方法,返回值為Bean類全名的String陣列

public class CustomImportSelector implements ImportSelector{
	@Override
	public String[] selectImports(AnnotationMetadata importingClassMetadata){
        //AnnotationMetadata:當前類的註解資訊
		//返回值bean的類全名
		return new String[]{"com.xx.User","com.xx.Dog"};
	}
}

介面ImportBeanDefinitionRegistrar:Spring提供的一個介面,可以根據需要通過BeanDefinitionRegistry註冊器註冊Bean

public class CustomImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

	/*
	*AnnotationMetadata:當前類的註解資訊
	*BeanDefinitionRegistry:BeanDefinition註冊類
	*/
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		boolean bean1 = registry.containsBeanDefinition("com.xxx.User");
		boolean bean2 = registry.containsBeanDefinition("com.xxx.Dog");
		// TODO 如果User和Dog同時存在於我們IOC容器中,那麼建立Cat類, 加入到容器
		// 對於我們要註冊的bean, 需要使用RootBeanDefinition進行封裝
		if(bean1 && bean2){
			RootBeanDefinition beanDefinition = new RootBeanDefinition(Cat.class);
			registry.registerBeanDefinition("cat", beanDefinition);
		}
	}

}

4.實現FactoryBean介面,和@Bean註解一起使用

@Configuration
public class Config {
	//通過Spring的工廠bean註冊
	@Bean
	public PigFactoryBean pigFactoryBean(){
		return new PigFactoryBean();
	}
}
public class PigFactoryBean implements FactoryBean<Pig>{

	@Override
	public Pig getObject() throws Exception {
		// TODO Auto-generated method stub
		return new Pig();
	}

	@Override
	public Class<?> getObjectType() {
		// TODO Auto-generated method stub
		return Pig.class;
	}
	
	@Override
	public boolean isSingleton() {
		return true;
	}
}

 

相關文章