当前位置: 首页 > news >正文

@Import整合第三方框架原理

@Import整合第三方框架原理

一、概述

Spring 与 MyBatis 注解方式整合有个重要的技术点就是 @Import,第三方框架与 Spring 整合 xml 方式很多是凭借自定义标签完成的,而第三方框架与 Spring 整合注解方式很多是靠 @Import 注解完成的。

@Import 可以导入如下三种类:

  • 普通的配置类
  • 实现 ImportSelector 接口的类
  • 实现 ImportBeanDefinitionRegistrar 接口的类

二、实验

普通的配置类的方式前面已经演示过了,可以看这篇文章:https://blog.csdn.net/2301_80749359/article/details/158066852?fromshare=blogdetail&sharetype=blogdetail&sharerId=158066852&sharerefer=PC&sharesource=2301_80749359&sharefrom=from_link,在这里就就不再演示了,直接从第二种开始。

2.1实现 ImportSelector 接口的类

1.创建类实现ImportSelector 接口(代码里面有注释了就不再详细解释了):

这里以注册OtherBean2为例

packagecom.itheima.imports;importcom.itheima.beans.OtherBean2;importorg.springframework.context.annotation.ComponentScan;importorg.springframework.context.annotation.ImportSelector;importorg.springframework.core.type.AnnotationMetadata;importjava.util.Map;publicclassMyImportSelector2implementsImportSelector{@OverridepublicString[]selectImports(AnnotationMetadataannotationMetadata){// 返回的数组是要注册到Spring的那些Bean的全限制定名returnnewString[]{OtherBean2.class.getName()};}}

2.在配置类中导入上面的类:

@Import(MyImportSelector2.class)

测试:

packagecom.itheima;importcom.itheima.beans.OtherBean2;importcom.itheima.config.SpringConfig2;importcom.itheima.dao.UserDao;importcom.itheima.dao.impl.UserDaoImpl3;importcom.itheima.service.UserService;importorg.springframework.context.annotation.AnnotationConfigApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext;importjavax.sql.DataSource;publicclassApplicationContextTest3{publicstaticvoidmain(String[]args){AnnotationConfigApplicationContextapplicationContextTest2=newAnnotationConfigApplicationContext(SpringConfig2.class);Objectobject2=applicationContextTest2.getBean(OtherBean2.class.getName());System.out.println(object2);}}

结果:

同时这里要进行拓展的是AnnotationMetadata,AnnotationMetadata叫做注解媒体数组,封装的是@Import类上的其他注解的信息,例如:

packagecom.itheima.config;importcom.alibaba.druid.pool.DruidDataSource;importcom.itheima.beans.OtherBean3;importcom.itheima.imports.MyImportSelector2;importorg.mybatis.spring.SqlSessionFactoryBean;importorg.mybatis.spring.annotation.MapperScan;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.*;importjavax.sql.DataSource;@Import(MyImportSelector2.class)//这个注解代表:这是一个核心配置类;这个类交给了Spring容器管理(就是相当于替换Spring配置文件)@Configuration//<context:component-scan base-package="com.itheima"/>:配置注解扫描,只有一个时直接写,有多个写成数组@ComponentScan("com.itheima")//<context:property-placeholder location="classpath:jdbc.properties"/>:引入配置文件@PropertySource("classpath:jdbc.properties")// <import resource="":导入其他配置类//@Import(OtherBean3.class)//下面是接口扫描// <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">//<!-- 指定要扫描的包-->// <property name="basePackage" value="com.itheima.mapper"></property>// </bean>@MapperScan("com.itheima.mapper")publicclassSpringConfig2{@Value("${jdbc.driver}")StringdriverClassName;@Value("${jdbc.url}")Stringurl;@Value("${jdbc.username}")Stringusername;@Value("${jdbc.password}")Stringpassword;@BeanpublicDataSourcedataSource(){DruidDataSourcedataSource=newDruidDataSource();dataSource.setDriverClassName(driverClassName);dataSource.setUsername(username);dataSource.setPassword(password);dataSource.setUrl(url);returndataSource;}@Bean// 在这里是通过类型进行注入的publicSqlSessionFactoryBeansqlSessionFactoryBean(DataSourcedataSource){// SqlSessionFactoryBean sqlSessionFactoryBean = sqlSessionFactoryBean(dataSource);SqlSessionFactoryBeansqlSessionFactoryBean=newSqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);returnsqlSessionFactoryBean;}}

这里SpringConfig2类上使用了@Import注解,那么AnnotationMetadata存储的是SpringConfig2类上的其他注解的信息,加入我们来获取@ComponentScan注解的元信息:

packagecom.itheima.imports;importcom.itheima.beans.OtherBean2;importorg.mybatis.spring.annotation.MapperScan;importorg.springframework.context.annotation.ComponentScan;importorg.springframework.context.annotation.ImportSelector;importorg.springframework.core.type.AnnotationMetadata;importjava.util.Map;publicclassMyImportSelector2implementsImportSelector{@OverridepublicString[]selectImports(AnnotationMetadataannotationMetadata){// AnnotationMetadata叫做注解媒体数组,封装的是@Import上的其他注解的信息// 定义一个Map来获取@Import注解上的其他注解的信息Map<String,Object>anootationAtrributes=annotationMetadata.getAnnotationAttributes(ComponentScan.class.getName());// return new String[0];anootationAtrributes.forEach((AtrributeName,AtrributeValue)->{System.out.println(AtrributeName+"=="+AtrributeValue);});// String[] basePackages = (String[]) anootationAtrributes.get("basePackages");// System.out.println(basePackages[0]);// 返回的数组是要注册到Spring的那些Bean的全限制定returnnewString[]{OtherBean2.class.getName()};}}

结果:

那么这样用什么用呢?当我们不想配置xml来注册Bean时可以使用这种方式了注册。具体在实际中的应用就是整合第三方框架,因为别人的框架都是配好的,我们只能通过这种形式了注册Bean,要么就是像上面一样自己写好一个实现ImportSelector 接口的类,使用@Import来进行导入,要么就像@MapperScan注解一样将@Import封装在某个注解里面。

Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE})@Documented@Import({MapperScannerRegistrar.class})@Repeatable(MapperScans.class)public@interfaceMapperScan{String[]value()default{};

2.2实现 ImportBeanDefinitionRegistrar 接口的类

1.定义类实现ImportBeanDefinitionRegistrar接口:

packagecom.itheima.imports;importcom.itheima.beans.OtherBean2;importorg.springframework.beans.factory.config.BeanDefinition;importorg.springframework.beans.factory.support.BeanDefinitionRegistry;importorg.springframework.beans.factory.support.BeanNameGenerator;importorg.springframework.beans.factory.support.RootBeanDefinition;importorg.springframework.context.annotation.ImportBeanDefinitionRegistrar;importorg.springframework.core.type.AnnotationMetadata;publicclassMyImportBeanDefinitionRegistrar2implementsImportBeanDefinitionRegistrar{@OverridepublicvoidregisterBeanDefinitions(AnnotationMetadataimportingClassMetadata,BeanDefinitionRegistryregistry,BeanNameGeneratorimportBeanNameGenerator){// 直接在这里定义BeanDefinition,然后再注册BeanDefinitionbeanDefinition=newRootBeanDefinition();beanDefinition.setBeanClassName(OtherBean2.class.getName());registry.registerBeanDefinition("otherBean2",beanDefinition);}}

底层是使用BeanDefinitionRegistry的registerBeanDefinition方法直接注册BeanDefinition进入BeanDefinitionMap当中。

2.在核心配置类中导入实现 ImportBeanDefinitionRegistrar 接口的类:

packagecom.itheima.config;importcom.alibaba.druid.pool.DruidDataSource;importcom.itheima.beans.OtherBean3;importcom.itheima.imports.MyImportSelector2;importorg.mybatis.spring.SqlSessionFactoryBean;importorg.mybatis.spring.annotation.MapperScan;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.*;importjavax.sql.DataSource;@Import(MyImportBeanDefinitionRegistrar2.class)//这个注解代表:这是一个核心配置类;这个类交给了Spring容器管理(就是相当于替换Spring配置文件)@Configuration//<context:component-scan base-package="com.itheima"/>:配置注解扫描,只有一个时直接写,有多个写成数组@ComponentScan("com.itheima")//<context:property-placeholder location="classpath:jdbc.properties"/>:引入配置文件@PropertySource("classpath:jdbc.properties")// <import resource="":导入其他配置类//@Import(OtherBean3.class)//下面是接口扫描// <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">//<!-- 指定要扫描的包-->// <property name="basePackage" value="com.itheima.mapper"></property>// </bean>@MapperScan("com.itheima.mapper")publicclassSpringConfig2{@Value("${jdbc.driver}")StringdriverClassName;@Value("${jdbc.url}")Stringurl;@Value("${jdbc.username}")Stringusername;@Value("${jdbc.password}")Stringpassword;@BeanpublicDataSourcedataSource(){DruidDataSourcedataSource=newDruidDataSource();dataSource.setDriverClassName(driverClassName);dataSource.setUsername(username);dataSource.setPassword(password);dataSource.setUrl(url);returndataSource;}@Bean// 在这里是通过类型进行注入的publicSqlSessionFactoryBeansqlSessionFactoryBean(DataSourcedataSource){// SqlSessionFactoryBean sqlSessionFactoryBean = sqlSessionFactoryBean(dataSource);SqlSessionFactoryBeansqlSessionFactoryBean=newSqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);returnsqlSessionFactoryBean;}}

测试:

packagecom.itheima;importcom.itheima.beans.OtherBean2;importcom.itheima.config.SpringConfig2;importcom.itheima.dao.UserDao;importcom.itheima.dao.impl.UserDaoImpl3;importcom.itheima.service.UserService;importorg.springframework.context.annotation.AnnotationConfigApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext;importjavax.sql.DataSource;publicclassApplicationContextTest3{publicstaticvoidmain(String[]args){AnnotationConfigApplicationContextapplicationContextTest2=newAnnotationConfigApplicationContext(SpringConfig2.class);Objectobject2=applicationContextTest2.getBean("otherBean2");System.out.println(object2);}}

当然也可以模仿将@MapperScan注解,将@Import封装于一个注解当中:

packagecom.itheima.anno;importcom.itheima.imports.MyImportBeanDefinitionRegistrar2;importorg.springframework.context.annotation.Import;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE})@Import(MyImportBeanDefinitionRegistrar2.class)public@interfaceMyMapperScan2{}

核心配置类中代码将"@Import(MyImportBeanDefinitionRegistrar2.class)“改为”@MyMapperScan2"即可,均能够运行:

http://www.jsqmd.com/news/387298/

相关文章:

  • 使用 Google Earth Engine 快速导出 Copernicus GLO-30 和 ASTER GDEM 高程数据
  • 现代控制理论(1)—— 概论
  • 05]delphi10.3中richedit中删除线
  • 关于学习技术栈的思考
  • 实测才敢推!自考必备的降AI率平台 —— 千笔·专业降AIGC智能体
  • 【Python】从0到1完成轻量级接口测试工具:基于Python+FastAPI+Pytest
  • 适用于室内和室外的集成式LED PCBA解决方案
  • 基础入门 Flutter for OpenHarmony:battery_plus 电池状态监控详解
  • ArcPy 脚本:批量生成郑州市 1990-2019 年空间分析结果(核密度、热点、平均中心、标准差椭圆)
  • 这次终于选对!圈粉无数的一键生成论文工具 —— 千笔AI
  • 2026年阿里巴巴/1688平台开户代运营权威评测:深圳昊客网络 脱颖而出 - 深圳昊客网络
  • WAC集团推出WAC建筑品牌,以先进、技术驱动的解决方案赋能照明设计师
  • 使用 ArcPy 批量裁剪建筑面矢量:根据城区边界提取城市建筑数据
  • 2026最新!千笔,专科生专属降AI神器
  • 毕业论文神器!千笔,备受喜爱的AI论文平台
  • Windows Powershell 打开即闪退 | Windows PowerShell 内部错误。加载托管的 Windows Powershell 失败,返回错误 80131018。
  • 强烈安利!千笔,口碑爆棚的一键生成论文工具
  • 服务器运维(四十)日服务器linux-ps分析工具—东方仙盟
  • 用 Python 批量提取 1990–2019 年高层建筑并按城市导出 Shapefile
  • delphi10.3中UpDown1使用
  • 【信息科学与工程学】【智能交通】第五篇 自动驾驶02
  • 看完就会:AI论文平台,千笔 VS 灵感风暴AI,本科生写作神器!
  • vue3+nodejs校园活动管理系统的设计与实现
  • 人工智能之核心基础 机器学习 第十八章 经典实战项目 - 实践
  • vue3+nodejs气象数据共享平台 天气预报数据共享系统
  • axure: 下拉菜单
  • 香港中巴租赁市场分析:2026口碑租赁公司哪家强?大巴租车/汽车租赁/跨境租车/班车租赁/跨境包车,租赁公司推荐 - 品牌推荐师
  • vue3+nodejs的运动减肥计划系统的设计与实现
  • 洋葱好坏腐烂检测数据集VOC+YOLO格式1015张3类别
  • vue3+nodejs基于智能推荐算法的网上生鲜销售系统 开题