@Import注解详解

news2025/1/12 22:54:33

@Import这个注解非常重要,而且在springboot项目当中随处可见,就拿springboot启动类来说,我们经常会遇到一些@Enable相关的注解,例如开启异步@EnableAsync、开启缓存支持@EnableCaching、开启定时任务@EnableScheduling等等…

目录

    • 一、@Import源码
    • 二、@Import官网介绍
    • 三、@Import的四种用法
    • 四、@Import扩展注解
    • 五、@ImportResource注解

一、@Import源码

点开源码会发现他没有使用其他特别的注解,就是用了三个元注解:

  • @Target({ElementType.TYPE}): 使用范围接口、类、枚举、注解
  • @Retention(RetentionPolicy.RUNTIME): @Retention是用来修饰注解的生命周期的,RetentionPolicy.RUNTIME代表的是不仅被保存到class文件中,jvm加载class文件之后,仍然存在;一直有效!
  • @Documented: @Documented和@Deprecated注解长得有点像,@Deprecated是用来标注某个类或者方法不建议再继续使用,@Documented只能用在注解上,如果一个注解@B,被@Documented标注,那么被@B修饰的类,生成Javadoc文档时,会显示@B。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
    Class<?>[] value();
}

二、@Import官网介绍

这些@Enable注解你点进去就发现都是使用的@Import注解,就是利用@Import注解来将指定的配置类加载到容器当中!

在这里插入图片描述

@Import属于spring当中的注解,在spring-context包下。@Import源码,以及官网解释该注解:https://github.com/spring-projects/spring-framework/blob/main/spring-context/src/main/java/org/springframework/context/annotation/Import.java

(1)源码注释比较清楚地说明了@Import注解的作用,这里我翻译一下:

  • 声明一个或多个Component(Component代表的是组件,或者可以理解为对象)
  • 提供等同于spring的xml配置中<import/>元素的功能,允许导入@Configuration类、ImportSelector的实现和ImportBeanDefinitionRegistrar的实现,当然也可以导入一个常规的类作为Component(类似于4.2版本后,利用AnnotationConfigApplicationContext类的register方法导入一个普通的类作为Component)
  • 在@Configuration中声明的Bean应该被@Autowired注解注入,可以自动连接bean本身,也可以自动连接声明bean的配置类实例,后者允许在@Configuration类的方法之间进行显式的、IDE友好的导航
  • 可以声明在类级别上,或者作为一个元注解
  • 可以用@ImportResource注解代替@Import注解,去导入xml配置

(2)根据上面的翻译,我总结一下@Import注解的用法

  • 作用:
    • 导入一个或多个Bean
    • 导入@Configuration类
    • 导入ImportSelector的实现类
    • 导入ImportBeanDefinitionRegistrar的实现类
  • 使用前提: @Import必须要在@controller、@Service、@Component、@Configuration、@Repository修饰的类下,并且要在springboot扫描范围内,这些注解修饰的类默认是必须和springboot启动类同包才会被扫描到,当然也可以手动指定扫描包。在启动类上使用@Import也是可以的!使用@Bean注解间接创建的对象当中使用@Import是不可以的。如下示例就是不可以的哦!
@Configuration
public class Myconfig {
	@Bean
    public MyconfigTest myconfigTest(){
        return new MyconfigTest();
    }
}

@Import({TestBean1.class})
public class MyconfigTest {
}

(3)这些用法或许只有一个目的,就是导入Bean。那为什么要这么麻烦,手动导入Bean呢,@ComponentScan不是可以自动扫描包注册Bean嘛?其实这里的原因有两点:

  • @ComponentScan一般只会扫到自己项目中的Bean,第三方jar包中的@Bean扫不到
  • @Import注解可以结合@Conditional注解使用,即条件导入,@Conditional在spring源码中也是大量用到,这个我后面会专题介绍

(4)@Import等同于之前的<import/>标签

官方解释:<import/>元素在Spring XML文件中用于帮助模块化配置一样,@Import注释允许从另一个配置类加载@Bean定义,如果您想要避免组件扫描,通过使用一些配置类作为入口点显式定义所有组件,Import尤其有用。

<beans>
    <import resource="services.xml"/>
    <import resource="resources/messageSource.xml"/>
    <import resource="/resources/themeSource.xml"/>

    <bean id="bean1" class="..."/>
    <bean id="bean2" class="..."/>
</beans>

三、@Import的四种用法

通过@Import注入对象的四种方式

理论我们都明白了,剩下来实操,首先定义四个类,我们分别用不同的方式将这四个类存到容器当中。

public class TestBean1 {
    @Override
    public String toString() {
        return super.toString() + "--我是TestBean1";
    }
}

public class TestBean2 {
    @Override
    public String toString() {
        return super.toString() + "--我是TestBean2";
    }
}

public class TestBean3 {
    @Override
    public String toString() {
        return super.toString() + "--我是TestBean3";
    }
}

public class TestBean4 {
    @Override
    public String toString() {
        return super.toString() + "--我是TestBean4";
    }
}

方式一:间接的@Configuration和@Bean注入

注意:ImportBeanByConfig类不能被@ComponentScan扫描到,如果扫描到通过@Configuration注解都可以将testBean2放入到容器当中了,用@Import注解导入它就没有意义了

@Configuration
public class ImportBeanByConfig {
    @Bean
    public TestBean2 testBean2(){
        return new TestBean2();
    }
}

方式二:创建ImportSelector实现

ImportSelector接口只定义了一个String[] selectImports(AnnotationMetadata importingClassMetadata);,用于指定需要注册为bean的Class名称。使用@Import引入了一个ImportSelector实现类后,会把实现类中返回的Class名称都定义为bean

public class ImportBeanByImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
    	// 这里全类名
        return new String[]{"com.gzl.cn.springbootcache.config.TestBean3"};
    }
}

方式三:创建ImportBeanDefinitionRegistrar实现

public class ImportBeanByImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TestBean4.class);
        registry.registerBeanDefinition("TestBean4", rootBeanDefinition);
    }
}

方式四:直接被注入(直接写要注入的类class)

ImportTest类是需要被@ComonentScan扫到的,否则@Import直接不会生效

@Import({TestBean1.class,
        ImportBeanByConfig.class,
        ImportBeanByImportSelector.class,
        ImportBeanByImportBeanDefinitionRegistrar.class})
@Configuration
public class ImportTest {
}

写一个Controller方法测试

正常使用@Autowired注解的话,假如容器当中没有这个对象是会报错的,所以我们这里设置为required = false,这样就算没有这个对象,启动不会报错。

@RestController
public class CommonController {
    @Autowired(required = false)
    private TestBean1 testBean1;
    @Autowired(required = false)
    private TestBean2 testBean2;
    @Autowired(required = false)
    private TestBean3 testBean3;
    @Autowired(required = false)
    private TestBean4 testBean4;

    @RequestMapping("/import")
    public void printImportBeanInfo() {
        System.out.println(testBean1);
        System.out.println(testBean2);
        System.out.println(testBean3);
        System.out.println(testBean4);
    }
}

测试结果:

在这里插入图片描述

将ImportTest类的@Import注释掉,再次访问HTTP接口,控制台打印日志如下:

在这里插入图片描述

四、@Import扩展注解

@ImportAutoConfiguration@EnableAutoConfiguration就是通过@Import注解所扩展出来的注解,@ImportAutoConfiguration应该用到的比较少,但是@EnableAutoConfiguration注解大家应该不陌生吧,他是springboot当中@SpringBootApplication启动注解当中的组合注解之一,读springboot源码基本上都需要了解这个的。

在这里插入图片描述

五、@ImportResource注解

早在以前我们注入bean都是 通过xml来实现的,springboot项目当中已经很少见了,都是通过注解来存放到容器当中的,@ImportResource就是将xml配置文件生效。接下来通过代码来演示他的作用。

(1)创建一个类

@Data
public class Student {
    private String name;
    private Integer age;
}

(2)添加applicationContext.xml

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="dog1" class="com.gzl.cn.springbootcache.config.Student">
        <property name="name" value="zhangsan"/>
        <property name="age" value="27"/>
    </bean>
</beans>

(3)添加配置

@Configuration
@ImportResource(locations = "classpath:applicationContext.xml")
public class Myconfig {
}

(4)添加测试

@RestController
public class CommonController {
    @Autowired(required = false)
    private Student student;

    @RequestMapping("/import")
    public void printImportBeanInfo() {
        System.out.println(student);
    }
}

(5)启动访问接口:打印如下,成功从容器当中取出。

在这里插入图片描述

假如把@ImportResource(locations = "classpath:applicationContext.xml")去掉打印如下:

在这里插入图片描述

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

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

相关文章

Oracle通过DBLINK访问达梦数据库

环境需求 需要安装配置以下相关软件&#xff1a; 1、Oracle Gateways 2、ODBC数据源&#xff08;gateway机器&#xff09; 3、达梦数据库软件&#xff08;gateway机器&#xff09; 安装配置 Windows环境 安装达梦数据库软件 安装步骤省略&#xff0c;可以参考DM 数据库…

【嵌入式Linux开发一路清障-连载02】Ubuntu22.04安装Shutter进行截图和标注

Ubuntu22.04安装Shutter进行截图和标注障碍 05&#xff0d;Ubuntu22.04中不会给截图做标注&#xff0c;写Bolg举步维艰命令行方式安装Shuttershutter中的常用命令为截取活动窗口设置快捷键安装gnome-web-photo截取长图--失败--未完待续小结下节预告障碍 05&#xff0d;Ubuntu22…

一起来部署项目-采购一台云服务器

前言 不会运维的程序员不是一个好程序员&#xff0c;你是这样认为吗&#xff1f;不&#xff0c;不重要&#xff0c;关键是很多小企业是让后端程序员去干运维的&#xff0c;省钱~~~o(╥﹏╥)o。特别是在YQ严重的当下&#xff0c;所以为了提高自己的竞争力&#xff0c;从今天起&…

万字爽文一篇带你掌握Java8新特性

陈老老老板说明&#xff1a;新的专栏&#xff0c;本专栏专门讲Java8新特性&#xff0c;把平时遇到的问题与Java8的写法进行总结&#xff0c;需要注意的地方都标红了&#xff0c;一起加油。本文是介绍Java8新特性与常用方法&#xff08;此篇只做大体介绍了解&#xff0c;之后会把…

Java8中LocalDate详解Date线程不安全的原因

LocalDate 分类分工 java.time.LocalDate ->只对年月日做出处理 java.time.LocalTime ->只对时分秒纳秒做出处理 java.time.LocalDateTime ->同时可以处理年月日和时分秒优点 除了使用起来更加简单和灵活&#xff0c;主要是传统的时期处理类Date、Calendar不是多线…

刷爆leetcode第十二期 0026 数组中数字出现的次数

编号0026 数组中数字出现的次数 一个整型数组 nums 里除两个数字之外&#xff0c;其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n)&#xff0c;空间复杂度是O(1)。 题目示例如下 这里其实是一道我一个月之前做的题目 在学弟的博客里刚好看…

【数据结构与算法】Java实现七大排序算法汇总

✨哈喽&#xff0c;进来的小伙伴们&#xff0c;你们好耶&#xff01;✨ &#x1f6f0;️&#x1f6f0;️系列专栏:【数据结构与算法】 ✈️✈️本篇内容: Java实现七大排序算法汇总&#xff01; &#x1f680;&#x1f680;由于本篇博客涉及代码较多&#xff0c;博主把代码都提…

刷爆leetcode第十一期 0023~0025

刷爆leetcode第十一期 编号0023 相同的树编号0024 对称二叉树编号0025 另一个树的子树编号0023 相同的树 给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是…

多旋翼无人机仿真 rotors_simulator:用键盘控制无人机飞行

多旋翼无人机仿真 rotors_simulator&#xff1a;用键盘控制无人机飞行前言书接上文接口测试键盘指令发布指令转换与发布修改 rotors_simulator 的控制接口节点测试前言 RotorS 是一个MAV gazebo 仿真系统。 提供了几种多旋翼仿真模型&#xff0c;例如 AscTec HummingbirdAsc…

PHP反序列化

序列化与反序列化 序列化 反序列是指把对象转换为字符串的过程&#xff0c;便于在内存、文件、数据库中保存、传输&#xff0c;PHP中使用serialize函数进行序列化。 <?phpclass Person{public $name"php";protected $id;private $age;}$a new Person();$a_se…

全排列笔记

14天阅读挑战赛 全排列 题目 给定一个 没有重复 数字的序列&#xff0c;返回其所有可能的全排列。 示例: 输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ] 解答 方法一&#xff1a;回溯 思路 从高中的数学知识我们可以知道 从[1,2,3…

如何在Linux上优雅地写代码-Linux生存指南

初入Linux&#xff0c;发现老是要面对一个命令行&#xff0c;大黑框&#xff0c;看不懂各种手册&#xff0c;写代码也是用vi/vim&#xff0c;难受的捉急。其实Linux下的各种工具&#xff0c;强大得超出你的想象&#xff0c;如果你初入Linux&#xff0c;那么你急需阅读这篇文章&…

操作系统的主要功能

目录 一. 处理机管理功能 1.1 进程控制 1.2 进程同步 1.3 进程通信 1.4 进程调度 二. 存储器管理功能 2.1 内存分配 2.2 内存保护 2.3 地址映射 2.4 内存扩充 三. 设备管理功能 3.1 缓冲管理 3.2 设备分配 3.3 设备处理 3.4 设备独立性和虚拟设备 四…

关于Python爬虫兼职,这里有一条高效路径

前言 昨天&#xff0c;一位00后前来报喜&#xff0c;也表达感谢。 他说&#xff0c;当初刚毕业啥也不会也找不到工作&#xff0c;最后听了我的&#xff0c;边学爬虫边做兼职项目&#xff0c;积极主动求职投简历&#xff0c;既可以兼职获得收益&#xff0c;也能积累项目经验谋求…

Linux:以K、M、G查看文件大小;

简介&#xff1a;灵活多变的查看文件的大小 历史攻略&#xff1a; Linux&#xff1a;sudo免密 python&#xff1a;执行dos命令、Linux命令 案例源码&#xff1a; # 以适当方式显示文件大小&#xff1a; ls -lh# 以byte显示文件大小&#xff1a; ls -l# 以M显示文件大小&am…

NR PUSCH(五) DMRS

微信同步更新欢迎关注同名modem协议笔记 PUSCH DMRS和PDSCH DMRS内容基本一样&#xff0c;但也有不同的地方&#xff0c;例如PUSCH 可能需要Transform precoding&#xff0c;port 对应0~11(DMRS configured type2)等等。先简单看看Transformprecoding的相关内容&#xff0c;Tr…

Excel数据分析实战之开宗明义: Excel与数据分析实战

大家好&#xff0c;我是爱编程的喵喵。双985硕士毕业&#xff0c;现担任全栈工程师一职&#xff0c;热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。喜欢通过博客创作的方式对所学的知识进行总结…

军用大数据 - Spark机器学习

文章目录第1关&#xff1a;Iris 分类任务描述相关知识1&#xff1a;观察数据集2&#xff1a;RFormula 特征提取3&#xff1a;pandas 的 concat 函数编程要求代码实现————————————————————————————————————————第2关&#xff1a;图片识…

网络原理 --- 传输层Ⅲ TCP协议中的滑动窗口,流量控制和拥塞控制

文章目录网络原理传输层TCP协议4.滑动窗口5.流量控制6.拥塞控制总结网络原理 介绍TCP/IP协议中每一层里面的核心内容~ 应用层传输层网络层数据链路层物理层 传输层TCP协议 4.滑动窗口 TCP能够保证可靠传输,但是失去了效率! 但是TCP希望能够在保证可靠性的前提下,尽可能地提…

达梦数据库在不修改SQL的情况下为SQL指定HINT

前言 在Oracle中可以使用outline、SQL PROFILE等手段去在无需修改SQL语句的情况下&#xff0c;来保证SQL执行计划在不同硬件环境下相同&#xff0c;从而保证SQL语句在不同环境的执行效率。那么&#xff0c;在达梦数据库中则可以使用SF_INJECT_HINT系统函数达到类似的效果。 SF…