核心接口:

组件扫描器:

开发过程中,需要根据需求加载必要的bean,排除指定bean

设定组件扫描加载过滤器:

  • 名称:@ComponentScan

  • 类型:类注解

  • 位置:类定义上方

  • 作用:设置spring配置加载类扫描规则

  • 范例:

@ComponentScan(value="com.itzhuzhu",           //设置基础扫描路径excludeFilters =                  //设置过滤规则,当前为排除过滤@ComponentScan.Filter(            //设置过滤器type= FilterType.ANNOTATION,  //设置过滤方式为按照注解进行过滤classes=Repository.class)     //设置具体的过滤项,过滤所有@Repository修饰的bean)
public  class SpringConfig(){}

includeFilters:设置包含性过滤器
excludeFilters:设置排除性过滤器
type:设置过滤器类型

自定义组件过滤器:

  • 名称:TypeFilter

  • 类型:接口

  • 作用:自定义类型过滤器

  • 范例:

@ComponentScan(value="com.itzhuzhu",excludeFilters =@ComponentScan.Filter(type= FilterType.CUSTOMclasses=MyTypeFilter.class) )
public  class SpringConfig{}
public class MyTypeFilter implements TypeFilter {@Override//加载的类满足要求,匹配成功public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {//通过参数获取加载的类的元数据ClassMetadata classMetadata = metadataReader.getClassMetadata();//通过类的元数据获取类的名称String className = classMetadata.getClassName();//如果加载的类名满足过滤器要求,返回匹配成功if(className.equals("com.itheima.service.impl.UserServiceImpl")){//返回true表示匹配成功,返回false表示匹配失败。此处仅确认匹配结果,不会确认是排除还是加入,排除/加入由配置项决定,与此处无关return true;}return false;}
}

自定义导入器:

  • bean只有通过配置才可以进入spring容器,被spring加载并控制,导入器可以不通过bean的方式加载

配置bean的方式如下:

  • XML文件中使用标签配置
  • 使用@Component及衍生注解配置
  • 企业开发过程中,通常需要配置大量的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默认为空数组)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.存入数组中basePackages = new String[] {basePackage};}//8.创建类路径扫描器ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);//9.创建类型过滤器(此处使用切入点表达式类型过滤器)TypeFilter typeFilter = new AspectJTypeFilter(expression,this.getClass().getClassLoader());//10.给扫描器加入类型过滤器scanner.addIncludeFilter(typeFilter);//11.创建存放全限定类名的集合Set<String> classes = new HashSet<>();//12.填充集合数据for (String basePackage : basePackages) {scanner.findCandidateComponents(basePackage).forEach(beanDefinition -> classes.add(beanDefinition.getBeanClassName()));}//13.按照规则返回return classes.toArray(new String[classes.size()]);}
}
@Configuration
@ComponentScan("com.itzhuzhu")
@Import(CustomeImportBeanDefinitionRegistrar.class)    // 加载导入器
public class SpringConfig {}

自定义注册器:

  • 名称:ImportBeanDefinitionRegistrar

  • 类型:接口

  • 作用:自定义bean定义注册器

  • 范例:

public class CustomeImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {private String expression;public CustomeImportBeanDefinitionRegistrar(){try {//初始化时指定加载的properties文件名Properties loadAllProperties = PropertiesLoaderUtils.loadAllProperties("import.properties");//设定加载的属性名expression = loadAllProperties.getProperty("path");} catch (IOException e) {e.printStackTrace();}}@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {//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默认为空数组)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.存入数组中basePackages = new String[] {basePackage};}//8.创建类路径扫描器ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry, false);//9.创建类型过滤器(此处使用切入点表达式类型过滤器)TypeFilter typeFilter = new AspectJTypeFilter(expression,this.getClass().getClassLoader());//10.给扫描器加入类型过滤器scanner.addIncludeFilter(typeFilter);//11.扫描指定包scanner.scan(basePackages);}
}

bean初始化过程解析:

bean初始化过程解析:

BeanFactoryPostProcessor

  • 作用:定义了在bean工厂对象创建后,bean对象创建前执行的动作,用于对工厂进行创建后业务处理

  • 运行时机:当前操作用于对工厂进行处理,仅运行一次

BeanPostProcessor

  • 作用:定义了所有bean初始化前后进行的统一动作,用于对bean进行创建前业务处理与创建后业务处理

  • 运行时机:当前操作伴随着每个bean的创建过程,每次创建bean均运行该操作

InitializingBean

  • 作用:定义了每个bean的初始化前进行的动作,属于非统一性动作,用于对bean进行创建前业务处理

  • 运行时机:当前操作伴随着任意一个bean的创建过程,保障其个性化业务处理

注意:上述操作均需要被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区别

  • FactoryBean:封装单个bean的创建过程

  • BeanFactory:Spring容器顶层接口,定义了bean相关的获取操作

Spring IOC扫描器与注册器相关推荐

  1. 【小家Spring】Spring注解驱动开发---向Spring Ioc容器中注册Bean的7种方式

    每篇一句 比你有钱的人一定会比你努力,而比你努力的人终有一天会比你有钱 前言 Spring是一个非常强大的反转控制(IOC)框架,以帮助分离项目组件之间的依赖关系.因此可以说Spring容器对Bean ...

  2. Spring:Spring IOC注解方式注册beanDefinition

    文章目录 1.美图 2.概述 3.案例 3.1 案例1 4.容器初始化 5.AnnotationConfigApplicationContext 5.1 registerBean 5.1.1 clas ...

  3. Spring IOC流程源码分析

    一.Spring 核心容器 IOC初始化过程 Spring 核心之 IOC 容器初体验 IOC 与 DI IOC(Inversion of Control)控制反转:所谓控制反转,就是把原先我们代码里 ...

  4. 21.手绘Spring IOC运行时序图

    1.再谈IOC与 DI IOC(lnversion of Control)控制反转:所谓控制反转,就是把原先我们代码里面需要实现的对象创 建.依赖的代码,反转给容器来帮忙实现.那么必然的我们需要创建一 ...

  5. Spring:源码解读Spring IOC原理

    2019独角兽企业重金招聘Python工程师标准>>> 一.什么是Ioc/DI? IOC容器:主要是完成了 完成对象的创建和依赖的管理注入等. 先从我们自己设计这样一个视角来考虑: ...

  6. 一步一步手绘Spring IOC运行时序图二(基于XML的IOC容器初始化)

    相关内容: 架构师系列内容:架构师学习笔记(持续更新) 一步一步手绘Spring IOC运行时序图一(Spring 核心容器 IOC初始化过程) 一步一步手绘Spring IOC运行时序图二(基于XM ...

  7. JavaEE之Spring框架(Spring IOC)的使用

    六.Spring框架 6.1 Spring框架的概念 Spring 是众多开源java项目中的一员,基于分层的javaEE应用一站式轻量级开源框架,主要核心是 IOC(控制反转/依赖注入)与 AOP( ...

  8. Spring IOC容器的依赖注入流程(收集和注册、分析和组装)

    Spring IOC容器的依赖注入流程 Spring IOC容器的依赖注入工作可以分为两个阶段: 阶段一:收集和注册 第一个阶段可以认为是构建和收集bean定义的阶段,在这个阶段中,我们可以通过XML ...

  9. spring ioc的包的扫描(基于注解)

    一.包扫描初始步骤源码分析 AnnotationConfigApplicationContext aac =new AnnotationConfigApplicationContext("c ...

最新文章

  1. 【BZOJ4653】[Noi2016]区间 双指针法+线段树
  2. [react-router] React-Router怎么设置重定向?
  3. 阿里CTO张建锋:明年双11将大规模应用含光AI芯片
  4. Hive内部表与外部表区别详细介绍
  5. mysql改根用户_MySQL数据库中复位根用户密码的方法 | 很文博客
  6. 知到网课创新创业学考试试题答案分享!
  7. 【过程记录】ArcGIS Pro打开.osgb文件
  8. 云计算机教室优缺点,云教室和传统机房的区别,终于有人把它说清了
  9. 个人sublime定制
  10. 都在谈中台,究竟什么是中台?
  11. C C++实现网络验证和本地验证
  12. iOS 新浪新闻首页卡片滚动特效实现
  13. Siggraph三角网格变形之拉普拉斯变换
  14. JavaWeb技术内幕二:Java IO工作机制
  15. python 调用Google Translate API进行翻译
  16. 阿尔法蛋机器人tf卡_阿尔法蛋机器人哪款好适合几岁孩子,超能蛋早教机真实效果评测(价格309元)...
  17. 使用Burp,nbsp;Sqlmap进行自动化SQL注入渗透测试
  18. 机器阅读理解技术初探Bi-DAF
  19. 《Google软件测试之道》—第2章2.5节与Web Driver的创建者Simon Stewart的对话
  20. matlab中图像的阈值分割,基于MATLAB的图像阈值分割技术汇总

热门文章

  1. java使用计算器完成加法、减法运算
  2. 职高学计算机走单招是,职高学生不用愁了,还有机会上本科,走“单招”或是最佳途径!...
  3. IDEA创建.properties文件
  4. python matplotlib模块教程_Python中的Matplotlib模块入门教程
  5. android 生成 资源文件,SVG-Android开源库——SVG生成Vector资源文件的编辑预览工具...
  6. oracle vitu,Supply Chain Management (SCM) a Manufacturing | Oracle Česká Republika
  7. 【Python】常用的数据类型介绍以及它们之间相互转化
  8. matplotlib的基本使用 附python代码详细讲解(基本图的绘制、样式、简单函数的使用)
  9. (python3.8)pygraphviz的下载安装配置(在python下)最新
  10. java文件名判断练习