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;一切围绕对…

Angular过滤器

Angular过滤器 在HTML中的模板绑定符号{{ }}内通过|符号来调用过滤器。例如&#xff0c;假设我们希望将字符串转换成大写&#xff0c;可以对字符串中的每个字符都单独进行转换操作&#xff0c;也可以使用过滤器&#xff1a; {{ name | uppercase }}  //大写 在JavaScript代码…

给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…

微信企业号-根据code获取成员信息(过期code)

二次请求获取成员信息时&#xff0c;会报如下错误&#xff1b; {"errcode": "40029","errmsg": "invalid code" }这种情况是code过期了&#xff0c;企业号开发文档明确的写着”通过成员授权获取到的code&#xff0c;每次成员授权带上的…

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;对数据层中多个操作进行组…

一、SQL语法——4-数据库约束

4-数据库约束 1.概述 &#xff08;1&#xff09;约束是在表上强制执行的数据校验规则&#xff0c;约束主要用于保证数据库里数据的完整性&#xff1b;此外当表中的数据存在相互依赖性时&#xff0c;可以保护相关的数据不被删除&#xff1b; &#xff08;2&#xff09;大部分数据…

黑马程序员博学谷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;一种用于设计创建…

中文转换成字节数组

由中文转换成字节数组时由于编码格式的不同&#xff0c;一个汉字所占的字节会有所不同&#xff0c;在做转换时需特别注意。 例如&#xff0c; String.teststr "中国"; byte [] leng teststr.getBytestf-8"); 此时leng长度为6&#xff0c;即一个汉字占3个字节…

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

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

【贪心算法】POJ-1017

一、题目 Description A factory produces products packed in square packets of the same height h and of the sizes 11, 22, 33, 44, 55, 66. These products are always delivered to customers in the square parcels of the same height h as the products have and of …

SpringMVC响应使用案例(带数据页面跳转,快捷访问路径,返回json数据)

页面跳转 转发&#xff08;默认&#xff09; RequestMapping("/showPage1") public String showPage1() {System.out.println("user mvc controller is running ...");// return "WEB_INF/pages/forward:page.jsp";这种方式不支持重定向&#…

HDU 2874 Connections between cities(LCA离线算法实现)

http://acm.hdu.edu.cn/showproblem.php?pid2874 题意&#xff1a; 求两个城市之间的距离。 思路&#xff1a; LCA题&#xff0c;注意原图可能不连通。 如果不了解离线算法的话&#xff0c;可以看我之前博客写的解释http://www.cnblogs.com/zyb993963526/p/7295894.html 1 #in…

SpringMVC中的异步请求-跨域访问

发送异步请求&#xff1a; <%page pageEncoding"UTF-8" language"java" contentType"text/html;UTF-8" %><a href"javascript:void(0);" id"testAjax">访问springmvc后台controller</a><br/> <…

P1080 国王游戏

题目描述 恰逢 H 国国庆&#xff0c;国王邀请 n 位大臣来玩一个有奖游戏。首先&#xff0c;他让每个大臣在左、右手上面分别写下一个整数&#xff0c;国王自己也在左、右手上各写一个整数。然后&#xff0c;让这 n 位大臣排成一排&#xff0c;国王站在队伍的最前面。排好队后&a…