javascript
Spring IOC扫描器与注册器
核心接口:
組件掃描器:
開發(fā)過程中,需要根據(jù)需求加載必要的bean,排除指定bean
設定組件掃描加載過濾器:
-
名稱:@ComponentScan
-
類型:類注解
-
位置:類定義上方
-
作用:設置spring配置加載類掃描規(guī)則
-
范例:
includeFilters:設置包含性過濾器
excludeFilters:設置排除性過濾器
type:設置過濾器類型
自定義組件過濾器:
-
名稱:TypeFilter
-
類型:接口
-
作用:自定義類型過濾器
-
范例:
自定義導入器:
- bean只有通過配置才可以進入spring容器,被spring加載并控制,導入器可以不通過bean的方式加載
配置bean的方式如下:
- XML文件中使用標簽配置
- 使用@Component及衍生注解配置
- 企業(yè)開發(fā)過程中,通常需要配置大量的bean,需要一種快速高效配置大量bean的方式
ImportSelector
-
名稱: ImportSelector
-
類型:接口
-
作用:自定義bean導入器
-
范例:
配置文件:
ClassName=com.itzhuzhu.dao.impl.AccountDaoImp,com.itzhuzhu.dao.impl.BookDaoImpl path=com.itzhuzhu.dao.impl.* public class CustomerImportSelector implements ImportSelector {private String expression;public CustomerImportSelector(){try {//初始化時指定加載的properties文件名Properties loadAllProperties = PropertiesLoaderUtils.loadAllProperties("import.properties");//設定加載的屬性名expression = loadAllProperties.getProperty("path");} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {//1.定義掃描包的名稱String[] basePackages = null;//2.判斷有@Import注解的類上是否有@ComponentScan注解if (importingClassMetadata.hasAnnotation(ComponentScan.class.getName())) {//3.取出@ComponentScan注解的屬性Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(ComponentScan.class.getName());//4.取出屬性名稱為basePackages屬性的值basePackages = (String[]) annotationAttributes.get("basePackages");}//5.判斷是否有此屬性(如果沒有ComponentScan注解則屬性值為null,如果有ComponentScan注解,則basePackages默認為空數(shù)組)if (basePackages == null || basePackages.length == 0) {String basePackage = null;try {//6.取出包含@Import注解類的包名basePackage = Class.forName(importingClassMetadata.getClassName()).getPackage().getName();} catch (ClassNotFoundException e) {e.printStackTrace();}//7.存入數(shù)組中basePackages = new String[] {basePackage};}//8.創(chuàng)建類路徑掃描器ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);//9.創(chuàng)建類型過濾器(此處使用切入點表達式類型過濾器)TypeFilter typeFilter = new AspectJTypeFilter(expression,this.getClass().getClassLoader());//10.給掃描器加入類型過濾器scanner.addIncludeFilter(typeFilter);//11.創(chuàng)建存放全限定類名的集合Set<String> classes = new HashSet<>();//12.填充集合數(shù)據(jù)for (String basePackage : basePackages) {scanner.findCandidateComponents(basePackage).forEach(beanDefinition -> classes.add(beanDefinition.getBeanClassName()));}//13.按照規(guī)則返回return classes.toArray(new String[classes.size()]);} } @Configuration @ComponentScan("com.itzhuzhu") @Import(CustomeImportBeanDefinitionRegistrar.class) // 加載導入器 public class SpringConfig {}自定義注冊器:
-
名稱:ImportBeanDefinitionRegistrar
-
類型:接口
-
作用:自定義bean定義注冊器
-
范例:
bean初始化過程解析:
bean初始化過程解析:
BeanFactoryPostProcessor
-
作用:定義了在bean工廠對象創(chuàng)建后,bean對象創(chuàng)建前執(zhí)行的動作,用于對工廠進行創(chuàng)建后業(yè)務處理
-
運行時機:當前操作用于對工廠進行處理,僅運行一次
BeanPostProcessor
-
作用:定義了所有bean初始化前后進行的統(tǒng)一動作,用于對bean進行創(chuàng)建前業(yè)務處理與創(chuàng)建后業(yè)務處理
-
運行時機:當前操作伴隨著每個bean的創(chuàng)建過程,每次創(chuàng)建bean均運行該操作
InitializingBean
-
作用:定義了每個bean的初始化前進行的動作,屬于非統(tǒng)一性動作,用于對bean進行創(chuàng)建前業(yè)務處理
-
運行時機:當前操作伴隨著任意一個bean的創(chuàng)建過程,保障其個性化業(yè)務處理
注意:上述操作均需要被spring容器加載才可以運行
bean初始化過程解析:
package config.postprocessor;import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;public class MyBeanFactory implements BeanFactoryPostProcessor {@Override//工廠后處理bean接口核心操作public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println("bean工廠制作好了,還有什么事情需要處理");} } package config.postprocessor;import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor;public class MyBean implements BeanPostProcessor {@Override//所有bean初始化前置操作public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("bean之前巴拉巴拉");System.out.println(beanName);return bean;}@Override//所有bean初始化后置操作public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("bean之后巴拉巴拉");return bean;} } import org.mybatis.spring.SqlSessionFactoryBean; import org.springframework.beans.factory.InitializingBean;public class EquipmentDaoImpl implements EquipmentDao,InitializingBean {public void save() {System.out.println("equipment dao running...");}@Override//定義當前bean初始化操作,功效等同于init-method屬性配置public void afterPropertiesSet() throws Exception {SqlSessionFactoryBean fb;System.out.println("EquipmentDaoImpl......bean ...init......");} }繁瑣的bean初始化過程處理:
FactoryBean
- 對單一的bean的初始化過程進行封裝,達到簡化配置的目的
FactoryBean與BeanFactory區(qū)別
-
FactoryBean:封裝單個bean的創(chuàng)建過程
-
BeanFactory:Spring容器頂層接口,定義了bean相關的獲取操作
總結
以上是生活随笔為你收集整理的Spring IOC扫描器与注册器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringMVC-HandlerInt
- 下一篇: Spring模板对象