ComponetScan 定義掃描規則
- value:指定要掃描的包
- excludeFilters=Filter[] 指定掃描的時候按照什么規則排除哪些組件。
- includeFilters=Filter[] 指定掃描的時候只需要包含哪些組件。(注意的是包掃描默認的是掃描所有的,也就是use-default-filters=”true”,所以需要設置為false。 這個和配置文件一樣)
- FilterType.ANNOTATION :按照注解的方式
- FilterType.ASSIGNABLE_TYPE:按照給定的類型
- FilterType.CUSTOM:使用自定義規則。 使用這個需要是TypeFilter的實現類
- FilterType.CUSTOM使用 案例如下:
- FilterType.ASPECTJ:使用ASPECTJ表達式(基本用不到)
- FilterType.REGEX :使用正則表達式
例子
@Configuration @ComponentScan(value = "feilong.example", useDefaultFilters = true, excludeFilters = { //過濾掉具體的注解下所有類 @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class}), // //過濾掉具體的類 @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {ConfigTest2.class}) }, //includeFilter里面的Filter是並集 includeFilters = { @ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class}) } ) public class MainConfig { @Bean public Person person() { return new Person("feilong", 20); } }
類MyTypeFilter 是自定義Filter, 注意: 之前被過濾掉的類如果再自定義Filter中符合要求, 也會被重新放到IOC容器中.
public class MyTypeFilter implements TypeFilter { @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { //獲取注解metaData AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); Resource resource = metadataReader.getResource(); //獲取當前類信息 ClassMetadata classMetadata = metadataReader.getClassMetadata(); String strClassName = classMetadata.getClassName(); System.out.println("通過自定義規則 ==>>>> " + strClassName); //返回true的類會被注冊進IOC return strClassName.contains("Controller"); } }
@Import[快速的給容器中導入一個組件]
@Import的三種用法:
(1)、 @Import(要導入容器中的組件);容器中就會自動的注冊這個組件,id默認是全類名
(2)、 ImportSelector :返回需要的組件的全類名的數組;
(3)、 ImportBeanDefinitionRegistrar : 手動注冊bean到容器中
1. 組件注冊-@Import
-給容器中快速導入一個組件
定義兩個POJO類
public class Color { } public class Red { }
將此類對應的Bean導入IOC容器
@Configuration @ComponentScan(value = "feilong.example") @Import({Color.class, Red.class}) public class MainConfig { }
2. 使用ImportSelector
創建自定義MyImportSelector , 在方法selectImports 中返回要注入的類
public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { return new String[]{"feilong.example.springbootlearn.Color","feilong.example.springbootlearn.Red"}; } }
將自定義ImportSeletor加入配置文件
@Configuration @ComponentScan(value = "feilong.example") @Import(MyImportSelector.class) public class MainConfig { }
3. 使用 ImportBeanDefinitionRegistrar接口,
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { registry.registerBeanDefinition("green", new RootBeanDefinition(Green.class)); } }
將自定義ImportSeletor加入配置文件
@Configuration @ComponentScan(value = "feilong.example") @Import({MyImportSelector.class,MyImportBeanDefinitionRegistrar.class}) public class MainConfig { }
執行結果如下
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
feilong.example.springbootlearn.Color
feilong.example.springbootlearn.Red
person
person3
green
使用FactoryBean注解
創建自定義的一個FactoryBean
public class MyColorFactoryBean implements FactoryBean<Color> { @Override public Color getObject() throws Exception { System.out.println("Creating Color Object by MyColorFactoryBean..."); return new Color(); } //控制是否為單例 // true:表示的就是一個單實例,在容器中保存一份 // false:多實例,每次獲取都會創建一個新的bean @Override public boolean isSingleton() { return true; } @Override public Class<?> getObjectType() { return Color.class; } }
配置為Bean
@Configuration @ComponentScan(value = "feilong.example") public class MainConfig { @Bean public Person person() { return new Person("feilong", 20); } @Bean("person3") public Person personCondition() { return new Person("feilong", 30); } @Bean public MyColorFactoryBean colorFactoryBean(){ return new MyColorFactoryBean(); } }
測試
public class MainTest { public static void main(String[] args) throws InterruptedException { ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class); String[] strName = ((AnnotationConfigApplicationContext) applicationContext).getBeanDefinitionNames(); for (String s : strName) { System.out.println(s); } //此處獲取的是getObject對象, 即Color對象 Color c = (Color) applicationContext.getBean("colorFactoryBean"); //此處獲取的是BeanFactory工廠對象本身 MyColorFactoryBean myColorFactoryBean =(MyColorFactoryBean) applicationContext.getBean("&colorFactoryBean"); System.out.println(c); System.out.println(myColorFactoryBean); } } /* org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory mainConfig person person3 colorFactoryBean Creating Color Object by MyColorFactoryBean... feilong.example.springbootlearn.Color@2a32de6c feilong.example.springbootlearn.MyColorFactoryBean@7692d9cc */
注意, 使用FactoryBean(工廠Bean) 默認獲取到的是工廠Bean調用方法getObject()獲取到的對象, 如果要想獲取到原來的Bean工廠本身,需要加上&,
Bean生命周期
* 容器管理bean的生命周期:
* 我們可以自定義初始化方法和銷毀的方法:容器在bean進行到當前的生命周期的時候,來調用我們自定義的初始化方法和銷毀方法
* 構造(對象創建):
* 單實例:在容器啟動的時候創建對象
* 多實例:在每次獲取的時候來創建對象
* 初始化方法:
* 對象創建完成,並賦值好,調用初始化方法
* 銷毀方法:
* 單實例的bean:在容器關閉的時候進行銷毀
* 多實例的bean:容器不會管理這個bean,容器不會調用銷毀的方法
生命周期-InitializingBean
和DisposableBean
定義測試類:
public class CarLifeCycle implements InitializingBean { public CarLifeCycle() { System.out.println("CarLifeCycle constructor..."); } public void init() { System.out.println("CarLifeCycle...init..."); } public void destroy() { System.out.println("CarLifeCycle...destroy..."); } @Override public void afterPropertiesSet() throws Exception { System.out.println("接口 InitializingBean # afterPropertiesSet "); } }
定義MyBeanPostProcessor
public class MyBeanPostProcessor implements BeanPostProcessor { public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println(beanName + " => MyBeanPostProcessor .. before"); return bean; } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println(beanName + " => MyBeanPostProcessor .. after"); return bean; } }
注入IOC
@Configuration @ComponentScan(value = "feilong.example") public class MainConfig { @Bean(initMethod = "init") public CarLifeCycle carLifeCycle(){ return new CarLifeCycle(); } }
執行程序
CarLifeCycle constructor... carLifeCycle => MyBeanPostProcessor .. before 接口 InitializingBean # afterPropertiesSet CarLifeCycle...init... carLifeCycle => MyBeanPostProcessor .. after