Spring基礎組件

@Configuration

指定配置類

@Bean

一般針對導入第三方的類或包的組件,比如在其他包中定義的Person類需要在我們的容器中使用

@ComponentScan

掃描Bean,一般針對我們自己使用的類,useDefaultFilters爲true時默認掃描@Component@Controller@Service@Repository

@Scope

掃描規則:

  • prototype(單實例):創建IOC容器時,實例Bean被創建
  • singleton(多實例):僅當Bean被使用時才創建
@Configuration
public class Config {
	//給容器中註冊一個bean, 類型爲返回值的類型, 默認是單實例
	/*
	 * prototype:多實例: IOC容器啓動的時候,IOC容器啓動並不會去調用方法創建對象, 而是每次獲取的時候纔會調用方法創建對象
	 * singleton:單實例(默認):IOC容器啓動的時候會調用方法創建對象並放到IOC容器中,以後每次獲取的就是直接從容器中拿(大Map.get)的同一個bean
	 * request: 主要針對web應用, 遞交一次請求創建一個實例
	 * session:同一個session創建一個實例
	 */
	@Scope("prototype")
	@Bean
	public Person person(){
		return new Person("person",20);
	}
}
@Lazy

懶加載:針對單實例Bean而言,容器啓動不創建對象,被使用時才創建

@Configuration
public class Config {
	//給容器中註冊一個bean, 類型爲返回值的類型, 默認是單實例
	/*
	 * 懶加載: 主要針對單實例bean:默認在容器啓動的時候創建對象
	 * 懶加載:容器啓動時候不創建對象, 僅當第一次使用(獲取)bean的時候才創建被初始化
	 */
	@Lazy
	@Bean
	public Person person(){
		System.out.println("給容器中添加person.......");
		return new Person("person",20);
	}
}
@Conditional

根據指定條件選擇性的註冊Bean,實現Conditional接口,重寫matches方法(條件爲判斷成功,返回true)

@Configuration
public class Config {
	@Bean("person")
	public Person person(){
		System.out.println("給容器中添加person.......");
		return new Person("person",20);
	}
	
	@Conditional(WinCondition.class)
	@Bean("person1")
	public Person person1(){
		System.out.println("給容器中添加person1.......");
		return new Person("person1",58);
	}
	@Conditional(LinCondition.class)
	@Bean("person2")//bean在容器中的ID爲james, IOC容器MAP,  map.put("id",value)
	public Person person2(){
		System.out.println("給容器中添加person2.......");
		return new Person("person2",20);
	}
}

public class WinCondition implements Condition{
	/*
	*ConditionContext: 判斷條件可以使用的上下文(環境)
	*AnnotatedTypeMetadata: 註解的信息
	*/
	@Override
	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		// TODO 是否爲WINDOW系統
		//能獲取到IOC容器正在使用的beanFactory
		ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
		//獲取當前環境變量(包括我們操作系統是WIN還是LINUX??)
		Environment environment = context.getEnvironment();
		String os_name = environment.getProperty("os.name");
		if(os_name.contains("Windows")){
			return true;
		}
		return false;
	}
}
@Import

快速給容器導入一個組件,手動添加組件到IOC容器,還可以使用ImportSelectorImportBeanDefinitionRegistrar自定義返回組件

ImportSelector是一個接口,返回需要導入到容器的組件的全類名數組
ImportBeanDefinitionRegistrar 實現此接口手動添加組件到IOC容器,所有Bean的註冊可以使用BeanDefinitionRegistrar

public class JamesImportSelector implements ImportSelector{
	@Override
	public String[] selectImports(AnnotationMetadata importingClassMetadata){
		//返回全類名的bean
		return new String[]{"com.bean.Fish","com.bean.Tiger"};
	}
}


public class JamesImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

	/*
	*AnnotationMetadata:當前類的註解信息
	*BeanDefinitionRegistry:BeanDefinition註冊類
	*    把所有需要添加到容器中的bean加入;
	*    @Scope
	*/
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		boolean bean1 = registry.containsBeanDefinition("com.bean.Dog");
		boolean bean2 = registry.containsBeanDefinition("com.bean.Cat");
		//如果Dog和Cat同時存在於我們IOC容器中,那麼創建Pig類, 加入到容器
		//對於我們要註冊的bean, 給bean進行封裝,
		if(bean1 && bean2){
			RootBeanDefinition beanDefinition = new RootBeanDefinition(Pig.class);
			registry.registerBeanDefinition("pig", beanDefinition);
		}
	}
}
實現FactoryBean接口

FactoryBean,實現FactoryBean接口可以通過此方法把bean注入到容器中
BeanFactory,可以從容器中獲取實例化後的Bean

@Configuration
@Import(value = { Dog.class,Cat.class, JamesImportSelector.class,JamesImportBeanDefinitionRegistrar.class })
public class Config {
	/*
	 * 給容器中註冊組件的方式
	 * 1,@Bean: [導入第三方的類或包的組件],比如Person爲第三方的類, 需要在我們的IOC容器中使用
	 * 2,包掃描+組件的標註註解(@ComponentScan:  @Controller, @Service  @Reponsitory  @ Componet),一般是針對 我們自己寫的類,使用這個
	 * 3,@Import:[快速給容器導入一個組件] 注意:@Bean有點簡單
	 *      a,@Import(要導入到容器中的組件):容器會自動註冊這個組件,bean 的 id爲全類名
	 *      b,ImportSelector:是一個接口,返回需要導入到容器的組件的全類名數組
	 *      c,ImportBeanDefinitionRegistrar:可以手動添加組件到IOC容器, 所有Bean的註冊可以使用BeanDifinitionRegistry
	 *          寫JamesImportBeanDefinitionRegistrar實現ImportBeanDefinitionRegistrar接口即可
	 *  4,使用Spring提供的FactoryBean(工廠bean)進行註冊 
	 */
	//容器啓動時初始化person的bean實例
	@Bean("person")
	public Person person(){
		return new Person("person",20);
	}
	@Bean
	public JamesFactoryBean jamesFactoryBean(){
		return new JamesFactoryBean();
	}
}

public class JamesFactoryBean implements FactoryBean<Monkey>{

	@Override
	public Monkey getObject() throws Exception {
		// TODO Auto-generated method stub
		return new Monkey();
	}
	@Override
	public Class<?> getObjectType() {
		// TODO Auto-generated method stub
		return Monkey.class;
	}
	@Override
	public boolean isSingleton() {
		return true;
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章