@Configuration
告訴Spring這是一個(gè)配置類作用在類上,同時(shí)該類會注冊在IOC容器中
@Bean
給容器中注冊一個(gè)Bean;類型為返回值的類型益老,id默認(rèn)是用方法名作為id
@ComponentScan
作用:指定掃描的包 锉罐。
有以下屬性
1.value:指定要掃描的包
2.excludeFilters = Filter[] :指定掃描的時(shí)候按照什么規(guī)則排除那些組件
3.includeFilters = Filter[] :指定掃描的時(shí)候只需要包含哪些組件
4.FilterType.ANNOTATION:按照注解
5.FilterType.ASSIGNABLE_TYPE:按照給定的類型辐烂;
6.FilterType.ASPECTJ:使用ASPECTJ表達(dá)式
7.FilterType.REGEX:使用正則指定
8.FilterType.CUSTOM:使用自定義規(guī)則
@ComponentScans(
value = {
@ComponentScan(value="com.atguigu.bean",includeFilters = {
/* @Filter(type=FilterType.ANNOTATION,classes={Controller.class}),
@Filter(type=FilterType.ASSIGNABLE_TYPE,classes={BookService.class}),*/
@Filter(type=FilterType.CUSTOM,classes={MyTypeFilter.class})
},useDefaultFilters = false)
}
)
其中自定義規(guī)則時(shí)要實(shí)現(xiàn)TypeFilter接口代碼如下:
public class MyTypeFilter implements TypeFilter {
/**
* metadataReader:讀取到的當(dāng)前正在掃描的類的信息
* metadataReaderFactory:可以獲取到其他任何類信息的
*/
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException {
// TODO Auto-generated method stub
//獲取當(dāng)前類注解的信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//獲取當(dāng)前正在掃描的類的類信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//獲取當(dāng)前類資源(類的路徑)
Resource resource = metadataReader.getResource();
String className = classMetadata.getClassName();
System.out.println("--->"+className);
if(className.contains("er")){
return true;
}
return false;
}
}
@Scope
@Scope:調(diào)整作用域
* prototype:多實(shí)例的:ioc容器啟動(dòng)并不會去調(diào)用方法創(chuàng)建對象放在容器中。
* 每次獲取的時(shí)候才會調(diào)用方法創(chuàng)建對象辛块;
* singleton:單實(shí)例的(默認(rèn)值):ioc容器啟動(dòng)會調(diào)用方法創(chuàng)建對象放到ioc容器中郊霎。以后每次獲取就是直接從容器(map.get())中拿姥饰,
* request:同一次請求創(chuàng)建一個(gè)實(shí)例
* session:同一個(gè)session創(chuàng)建一個(gè)實(shí)例
參照spring源碼:
ConfigurableBeanFactory#SCOPE_PROTOTYPE
@see ConfigurableBeanFactory#SCOPE_SINGLETON
@see
org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST request
@see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION sesssion
@Lazy
懶加載:容器啟動(dòng)不創(chuàng)建對象。第一次使用(獲取)Bean創(chuàng)建對象鲤屡,并初始化损痰;但是單實(shí)例bean:默認(rèn)在容器啟動(dòng)的時(shí)候創(chuàng)建對象;
@Lazy
@Bean("person")
public Person person(){
System.out.println("給容器中添加Person....");
return new Person("張三", 25);
}
@Conditional
- 作用在類上,類中組件統(tǒng)一設(shè)置酒来。滿足當(dāng)前條件卢未,這個(gè)類中配置的所有bean注冊才能生效;
- 作用在方法上堰汉,滿足條件給容器中注冊bean
//類中組件統(tǒng)一設(shè)置辽社。滿足當(dāng)前條件,這個(gè)類中配置的所有bean注冊才能生效翘鸭;
@Conditional({WindowsCondition.class})
public class MainConfig2
- WindowsCondition該類需要實(shí)現(xiàn)Conditional接口
//判斷是否windows系統(tǒng)
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
if(property.contains("Windows")){
return true;
}
return false;
}
}
@Import
- 快速給容器中導(dǎo)入一個(gè)組件 容器中就會自動(dòng)注冊這個(gè)組件滴铅,id默認(rèn)是全類名
@Import({Color.class,Red.class})
//@Import導(dǎo)入組件,id默認(rèn)是組件的全類名
public class MainConfig2
- ImportSelector:返回需要導(dǎo)入的組件的全類名數(shù)組
@Import({MyImportSelector.class})
//自定義邏輯返回需要導(dǎo)入的組件
public class MyImportSelector implements ImportSelector {
//返回值就乓,就是到導(dǎo)入到容器中的組件全類名
//AnnotationMetadata:當(dāng)前標(biāo)注@Import注解的類的所有注解信息
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
// TODO Auto-generated method stub
//importingClassMetadata
//方法不要返回null值
return new String[]{"com.atguigu.bean.Blue","com.atguigu.bean.Yellow"};
}
}
- ImportBeanDefinitionRegistrar:手動(dòng)注冊bean到容器中
@Import({MyImportBeanDefinitionRegistrar.class})
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* AnnotationMetadata:當(dāng)前類的注解信息
* BeanDefinitionRegistry:BeanDefinition注冊類汉匙;
* 把所有需要添加到容器中的bean;調(diào)用
* BeanDefinitionRegistry.registerBeanDefinition手工注冊進(jìn)來
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean definition = registry.containsBeanDefinition("com.atguigu.bean.Red");
boolean definition2 = registry.containsBeanDefinition("com.atguigu.bean.Blue");
if(definition && definition2){
//指定Bean定義信息档址;(Bean的類型盹兢,Bean。守伸。绎秒。)
RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
//注冊一個(gè)Bean,指定bean名
registry.registerBeanDefinition("rainBow", beanDefinition);
}
}
}
FactoryBean的使用
- 默認(rèn)獲取到的是工廠bean調(diào)用getObject創(chuàng)建的對象
- 要獲取工廠Bean本身尼摹,我們需要給id前面加一個(gè)& &colorFactoryBean
@Bean
public ColorFactoryBean colorFactoryBean(){
return new ColorFactoryBean();
}
//創(chuàng)建一個(gè)Spring定義的FactoryBean
public class ColorFactoryBean implements FactoryBean<Color> {
//返回一個(gè)Color對象见芹,這個(gè)對象會添加到容器中
@Override
public Color getObject() throws Exception {
// TODO Auto-generated method stub
System.out.println("ColorFactoryBean...getObject...");
return new Color();
}
@Override
public Class<?> getObjectType() {
// TODO Auto-generated method stub
return Color.class;
}
//是單例剂娄?
//true:這個(gè)bean是單實(shí)例,在容器中保存一份
//false:多實(shí)例玄呛,每次獲取都會創(chuàng)建一個(gè)新的bean阅懦;
@Override
public boolean isSingleton() {
// TODO Auto-generated method stub
return false;
}
}