Spring IOC扫描器与注册器

核心接口:

在这里插入图片描述

组件扫描器:

开发过程中,需要根据需求加载必要的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相关的获取操作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/572161.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring AOP切入点与通知XML类型

AOP&#xff1a; AOP(Aspect Oriented Programing)面向切面编程&#xff0c;一种编程范式&#xff0c;隶属于软工范畴&#xff0c;指导开发者如何组织程序结构AOP弥补了OOP的不足&#xff0c;基于OOP基础之上进行横向开发 uOOP规定程序开发以类为主体模型&#xff0c;一切围绕对…

给iOS项目中添加图片,并通过UIImageView引用和显示该UIImage图片

【问题】 关于iOS/iPhone中的文件选择对话框&#xff0c;用于用户去选择图片等文件 过程中&#xff0c;问题转换为&#xff0c;需要给当前iOS项目中&#xff0c;添加一个图片。 类似于Windows开发中的资源文件&#xff0c;其中图片文件属于资源的一种。 并且&#xff0c;接着可…

AOP底层原理与注解配置详解

注解开发AOP制作步骤&#xff1a; 在XML格式基础上 导入坐标&#xff08;伴随spring-context坐标导入已经依赖导入完成开启AOP注解支持配置切面Aspect定义专用的切入点方法&#xff0c;并配置切入点Pointcut为通知方法配置通知类型及对应切入点Before 注解开发AOP注意事项&am…

MacOS Apple M1 安装ARM架构的JDK及动态切换版本

JDK下载安装&#xff1a; 咱就是说&#xff0c;ARM版本的JDK就是一个字&#xff0c;真特么快&#xff0c;想变快吗&#xff0c;赶紧下载叭&#xff01;&#xff01; 1、下载地址&#xff1a;https://www.azul.com/downloads/?packagejdk 筛选一下MacOS下ARM架构的JDK版本&…

梯度下降和EM算法,kmeans的em推导

I. 牛顿迭代法给定一个复杂的非线性函数f(x)&#xff0c;希望求它的最小值&#xff0c;我们一般可以这样做&#xff0c;假定它足够光滑&#xff0c;那么它的最小值也就是它的极小值点&#xff0c;满足f′(x0)0&#xff0c;然后可以转化为求方程f′(x)0的根了。非线性方程的根我…

Spring事务详解与使用

Spring事务核心对象 J2EE开发使用分层设计的思想进行&#xff0c;对于简单的业务层转调数据层的单一操作&#xff0c;事务开启在业务层或者数据层并无太大差别&#xff0c;当业务中包含多个数据层的调用时&#xff0c;需要在业务层开启事务&#xff0c;对数据层中多个操作进行组…

黑马程序员博学谷Java就业班课程

1、资料全无加密&#xff0c;可任意试看 2、内容包括课程资料 地址:https://www.boxuegu.com/class/outline-1112.html

设计模式一の设计模式详解

一、设计模式定义 设计模式&#xff08;Design Pattern&#xff09;是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。使用设计模式的目的&#xff1a;为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模式使代码编写真正工程化&#xff1b;…

Spring模板对象

Spring模块对象: 把共性的方法抽取出来固定为一个模板&#xff0c;后续再操作只需要填充内容即可。 比如&#xff1a;淘宝每次买东西都要填写地址&#xff0c;只是每次买的东西不一样&#xff0c;所以可以做一个默认地址&#xff0c;每次买东西都要去选商品就行了&#xff0c;不…

SpringMVC入门案例

SpringMVC 概述&#xff1a; SpringMVC是一种基于Java实现MVC模型的轻量级Web框架 三层架构 表现层&#xff1a;负责数据展示业务层&#xff1a;负责业务处理数据层&#xff1a;负责数据操作 MVC&#xff08;Model View Controller&#xff09;&#xff1a;一种用于设计创建…

SpringMVC请求中的普通、POJO、数组集合类型传参与类转换器

SpringMVC将传递的参数封装到处理器方法的形参中&#xff0c;达到快速访问参数的目的。 普通类型参数传参 参数名与处理器方法形参名保持一致 访问URL&#xff1a; http://localhost/requestParam1?nameitzhuzhu&age14 RequestMapping("/requestParam1")publi…

SpringMVC-HandlerInterceptor拦截器的使用与参数详解

拦截器概念&#xff1a; 拦截器&#xff08; Interceptor&#xff09;是一种动态拦截方法调用的机制&#xff0c;请求处理过程解析核心原理&#xff1a; AOP思想拦截器链&#xff1a;多个拦截器按照一定的顺序&#xff0c;对原始被调用功能进行增强 作用&#xff1a; 在指定的…

使用FindBugs-IDEA插件找到代码中潜在的问题

另一篇使用文档&#xff0c;参照&#xff1a;https://www.cnblogs.com/huaxingtianxia/p/6703315.html 我们通常都会在APP上线之后,发现各种错误,尤其是空指针异常,这些错误对于用户体验来说是非常不好的,但其实大部分的问题,我们都能够提前发现. 在编写代码的过程中,可能不会时…

霍炬:再谈百度:KPI、无人机,以及一个必须给父母看的案例

霍炬&#xff1a;再谈百度&#xff1a;KPI、无人机&#xff0c;以及一个必须给父母看的案例 作者&#xff1a;霍炬。 原文链接&#xff1a;http://www.donews.com/idonews/article/8147.shtm没想到我之前的一篇关于百度的文章引起了这么大的反馈。非常多朋友称赞我写的好&…

使用SpringMVC模拟文件上传与下载案例

文件上传下载 SpringMVC封装了Tomcat的上传文件功能 MultipartResolver接口 MultipartResolver接口定义了文件上传过程中的相关操作&#xff0c;并对通用性操作进行了封装MultipartResolver接口底层实现类CommonsMultipartResovlerCommonsMultipartResovler并未自主实现文件上…

JSR表单校验框架

表单校验的重要性&#xff1a; 表单校验保障了数据有效性、安全性 不适用表单检验数据可以随意输入&#xff0c;导致错误的结果。后端表单校验的重要性&#xff0c;比如输入框采集成绩&#xff0c;如果前端做了检验&#xff0c;但是用户比较牛逼&#xff0c;他在地址栏上直接加…

使用Phantom omni力反馈设备控制机器人

传统的工业机器人普遍采用电机 、齿轮减速器 、关节轴三者直接连接的传动机构&#xff0c;这种机构要求电机与减速器安装在机械臂关节附近&#xff0c;其缺点是对于多关节机械臂&#xff0c;下一级关节的电机与减速器等驱动装置成为上一级关节的额外负载 。这一额外负载带来的负…

Go_配置系统环境MacOS(M1)

在MacOS下和JDK一样&#xff0c;配不配环境其实MacOS都是可以检测的到的&#xff0c;安装好以后直接输入go version是一样可以的&#xff0c;因为都是使用开发工具的&#xff0c;在开发工具里配置的话是样的&#xff0c;如果有习惯的话就配置一下吧 下载安装及配置环境&#xf…

Go_数据类型

数据类型&#xff1a; 计算机存储设备最小信息单位是位&#xff08;bit&#xff09;&#xff0c;最小的存储单元是字节&#xff08;byte&#xff09;&#xff0c;占用字节的不同&#xff0c;所表示能存储的数据长度不同。数据类型用来说明数据的数据的结构&#xff0c;便于后面…

HashMap之扰动函数和低位掩码

我们都知道&#xff0c;hashMap在实现的时候&#xff0c;为了寻找在数组上的位置&#xff0c;主要做了两件事 int hash hash(key); int i indexFor(key, table.length); 这个时候得到i才是数组上的位置。 这两个方法详解如下 JDK8对扰动函数的修改&#xff0c;只进行了一次移…