【Spring Boot】SpringBoot自动装配-Import

目录

    • 一、前言
    • 二、 定义
    • 三、使用说明
      • 3.1 创建项目
        • 3.1.1 导入依赖
        • 3.1.2 创建User类
      • 3.2 测试导入Bean
        • 3.2.1 修改启动类
      • 3.3 测试导入配置类
        • 3.3.1 创建UserConfig类
        • 3.3.2 修改启动类
      • 3.4 测试导入ImportSelector
        • 3.4.1 创建UseImportSelector类
        • 3.4.2 修改启动类
        • 3.4.3 启动测试
      • 3.5 测试导入ImportBeanDefinitionRegistrar类
        • 3.5.1 创建UserImportBeanDefinitionRegistrar
        • 3.5.2 修改启动类
      • 3.6 小结
    • 四、 改进
      • 4.1 创建注解
      • 4.2 修改启动类
    • 五、 验证
      • 5.1 创建项目
      • 5.2 创建user模块
        • 5.2.1 导入依赖
        • 5.2.2 创建User类
        • 5.2.3 修改启动类
      • 5.3 创建book-manage模块
        • 5.3.1 导入依赖
        • 5.3.2 修改启动类
    • 六、 在user模块中添加Enable注解
    • 七、小结

在这里插入图片描述
在这里插入图片描述

一、前言

@Import导入的类会被Spring加载到IOC容器中。而@Import提供4中用法:

  1. 导入Bean

  2. 导入配置类

  3. 导入 ImportSelector 实现类。一般用于加载配置文件中的类

  4. 导入 ImportBeanDefinitionRegistrar 实现类。

二、 定义

@Import注解定义如下,其内部只有一个参数为Class对象数组

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {Class<?>[] value();
}

三、使用说明

通过一个简单的小例子测试一下@Import是不是真的能实现Bean的注入

3.1 创建项目

在这里插入图片描述

3.1.1 导入依赖

这里我们除了springboot依赖,再添加个lombok依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.3</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.ldx</groupId><artifactId>import-annotation</artifactId><version>0.0.1-SNAPSHOT</version><name>import-annotation</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build>
</project>
3.1.2 创建User类
package com.ldx.importannotation;import lombok.AllArgsConstructor;
import lombok.Data;/*** 用户信息实体* @author ludangxin* @date 2021/8/1*/
@Data
@AllArgsConstructor
public class User {public User() {this.name = "李四";this.age = 13;}private String name;private Integer age;
}

3.2 测试导入Bean

3.2.1 修改启动类
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;@Slf4j
// 注入UserBean
@Import(value = User.class)
@SpringBootApplication
public class ImportAnnotationApplication {public static void main(String[] args) {ConfigurableApplicationContext applicationContext = SpringApplication.run(ImportAnnotationApplication.class, args);User user = applicationContext.getBean(User.class);log.info("user info ==={}",user);}
}

3.3 测试导入配置类

3.3.1 创建UserConfig类
import org.springframework.context.annotation.Bean;/*** 用户配置类* @author ludangxin* @date 2021/8/1*/
public class UserConfig {@Beanpublic User getUser(){return new User();}
}
3.3.2 修改启动类

将启动类上的@Import的value指向UserConfig类

@Import(value = UserConfig.class)

UserBean注入成功。

3.4 测试导入ImportSelector

3.4.1 创建UseImportSelector类
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;/*** 用户Bean选择器配置类* @author ludangxin* @date 2021/8/1*/
public class UseImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {// 指定User类的全限类名return new String[]{"com.ldx.importannotation.User"};}
}
3.4.2 修改启动类

将启动类上的@Import的value指向UseImportSelector类

@Import(value = UseImportSelector.class)
3.4.3 启动测试

UserBean注入成功。

3.5 测试导入ImportBeanDefinitionRegistrar类

3.5.1 创建UserImportBeanDefinitionRegistrar
package com.ldx.importannotation;import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;/*** 用户Bean定义注册配置类* @author ludangxin* @date 2021/8/1*/
public class UserImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {// 创建User类型的Bean的定义BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();// 将创建的UserBean定义注册到SpringRegistry中,其名称为userregistry.registerBeanDefinition("user", beanDefinition);}
}
3.5.2 修改启动类

将启动类上的@Import的value指向UserImportBeanDefinitionRegistrar类

@Import(value = UserImportBeanDefinitionRegistrar.class)

3.6 小结

简介中介绍的四种方式都可以注入UserBean。

好处:

  1. 导入指定的Bean或配置类。例如:由于业务需要将包路径或者需要加载的Bean类不在@ComponentScan的扫描范围内,这时候我们就可以通过@Import来实现Bean的注入。
  2. ImportSelector方式是制定需要加载类的全限类名。这时候我们就可以将我们的需要装载的类写到配置文件中,比如某个txt中,然后项目启动的时候读取txt中的全限类名,实现Bean的装载。SpringBoot就是使用这种方式实现的自动装配。

四、 改进

上面的例子通过使用@Import注解实现了spring bean的自动注入。但是装载Bean每次都得指定Bean的类或者配置类,在生产环境中我们在使用第三方Jar的时候根本不知道应该使用哪个配置文件或者压根就不知道配置文件的名称。这时我们其实可以扩展一个注解来优化这个问题。

4.1 创建注解

package com.ldx.importannotation;import org.springframework.context.annotation.Import;
import java.lang.annotation.*;/*** 启用User配置信息注解* @author ludangxin* @date 2021/8/1*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
// 指定需要导入的UserBean的配置类
@Import(UseImportSelector.class)
public @interface EnableUser {}

4.2 修改启动类

注掉之前的@Import,使用刚创建的@EnableUser注解

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;@Slf4j
//@Import(value = UserImportBeanDefinitionRegistrar.class)
@EnableUser
@SpringBootApplication
public class ImportAnnotationApplication {public static void main(String[] args) {ConfigurableApplicationContext applicationContext = SpringApplication.run(ImportAnnotationApplication.class, args);User user = applicationContext.getBean(User.class);log.info("user info ==={}",user);}
}

UserBean注入成功。

思考🤔
SpringBoot项目中能不能直接获取或者使用Jar包中的Bean呢?

五、 验证

5.1 创建项目

user模块为Bean的提供者,book-manage通过引入user模块Jar,来验证项目中能不能直接使用Jar中的Bean

5.2 创建user模块

5.2.1 导入依赖

没啥特别的依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.3</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.ldx</groupId><artifactId>user</artifactId><version>0.0.1-SNAPSHOT</version><name>user</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>
5.2.2 创建User类
package com.ldx.user;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;/*** 用户信息类* @author ludangxin* @date 2021/8/1*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {private Integer id;private String name;/*** 角色状态吗 1.管理员 2.老师 3.学生*/private Character role;private Integer age;public User getUserInfo() {return new User(66, "张三", '3', 21);}/*** 获取其任课老师信息*/public List<User> getTeachers() {List<User> users = new ArrayList<>();User user = new User();user.setId(2);user.setName("王麻子");user.setAge(45);user.setRole('2');User user1 = new User();user1.setId(3);user1.setName("李四");user1.setAge(35);user1.setRole('2');users.add(user);users.add(user1);return users;}
}
5.2.3 修改启动类
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;@Slf4j
@SpringBootApplication
public class UserApplication {public static void main(String[] args) {ConfigurableApplicationContext applicationContext = SpringApplication.run(UserApplication.class, args);User user = applicationContext.getBean(User.class);user.getTeachers().forEach(obj ->log.info("user teacher info ==={} ", obj));}@Beanpublic User getUser() {return new User();}
}

5.3 创建book-manage模块

5.3.1 导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.3</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.ldx</groupId><artifactId>book-manage</artifactId><version>0.0.1-SNAPSHOT</version><name>book-manage</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- user模块依赖 --><dependency><groupId>com.ldx</groupId><artifactId>user</artifactId><version>0.0.1-SNAPSHOT</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>
5.3.2 修改启动类

直接获取User Bean 并调用getUserInfo方法

import com.ldx.user.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;@Slf4j
@SpringBootApplication
public class BookManageApplication {public static void main(String[] args) {ConfigurableApplicationContext applicationContext = SpringApplication.run(BookManageApplication.class, args);User user = applicationContext.getBean(User.class);log.info("user info === {}", user.getUserInfo());}}

六、 在user模块中添加Enable注解

import org.springframework.context.annotation.Import;
import java.lang.annotation.*;/*** 启用User配置信息注解* @author ludangxin* @date 2021/8/1*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(User.class)
public @interface EnableUser {}

七、小结

不能直接在当前项目中使用Jar中的Bean(SpringBoot默认使用ImportSelector的方式加载META-INF/spring.factories中指定的配置类,会导致只需要导入相应的第三方Jar就可以使用其环境中的Bean)
可以在当前项目中使用Jar包中提供的Enable注解来导入Jar的Bean配置

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

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

相关文章

LibSVM介绍及使用

介绍 LibSVM 是一个广泛使用的开源库&#xff0c;用于支持向量机&#xff08;SVM&#xff09;的实现。它由台湾大学的 Chih-Chung Chang 和 Chih-Jen Lin 开发。LibSVM 提供了一种简单易用的接口&#xff0c;支持多种 SVM 变体&#xff0c;包括分类、回归和分布估计。以下是一些…

Docker-compose:管理多个容器

Docker-Compose 是 Docker 公司推出的一个开源工具软件&#xff0c;可以管理多个 Docker 容器组成一个应用。用户需要定义一个 YAML 格式的配置文件 docker-compose.yml&#xff0c;写好多个容器之间的调用关系。然后&#xff0c;只要一个命令&#xff0c;就能同时启动/关闭这些…

大数据-132 - Flink SQL 基本介绍 与 HelloWorld案例

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

uniapp离线(本地)打包

安卓离线打包 注意&#xff1a;jdk建议选择1.8 下载Android Studio配置gradle仓库地址 第一步&#xff1a;先下载对应的版本&#xff0c;进行压缩包解压 第二步&#xff1a;在电脑磁盘&#xff08;D盘&#xff09;&#xff0c;创建文件夹存放压缩包并进行解压&#xff0c;并创…

Netty笔记03-组件Channel

文章目录 Channel概述Channel 的概念Channel 的主要功能Channel 的生命周期Channel 的状态Channel 的类型channel 的主要方法 ChannelFutureCloseFuture&#x1f4a1; netty异步提升的是什么要点总结 Channel概述 Channel 的概念 在 Netty 中&#xff0c;Channel 是一个非常重…

SpringDoc介绍

一、SpringDoc 官方文档 1.1何为SpringDoc SpringDoc是一个用来自动生成API文档的库。它是基于SpringBoot项目的&#xff0c;遵循OpenAPI3(一个组织规定的规范)规范。它是通过检查我们运行中的程序&#xff0c;推断出基于Spring配置、类结构和各种注解的API语义&#xff0c;从…

网络(三)——协议是什么???

文章目录 协议的概念结构化数据网络计算机服务端定制协议客户端代码 协议的概念 计算机之间的传输媒介是光信号和电信号。通过 “频率” 和 “强弱” 来表示 0 和 1 这样的信息。要想传递各种不同的信息&#xff0c;就需要约定好双方的数据格式。 结构化数据 我们知道TCP是面向…

pgrouting实战应用

1&#xff09;下载地区地区数据&#xff08;下载数据是XYZM 四位数据&#xff09; 2&#xff09;下载裁剪行政区数据 3&#xff09;使用arcgis pro添加路网数据和行政区数据 4&#xff09;裁剪数据&#xff0c;仅历下行政区路网 5&#xff09;arcgis pro要素转线&#xff0…

TalkSphere项目介绍

TalkSphere项目介绍 文章目录 TalkSphere项目介绍一、前言二、技术栈及开发环境三、主要功能&#xff08;一&#xff09;用户登录与注册&#xff08;二&#xff09;用户历史消息展示&#xff08;三&#xff09;在线用户实时聊天 四、结语 一、前言 在线聊天室作为一个虚拟社交…

springboot3.X版本集成mybatis遇到的问题

由于我本地springboot为3.x版本&#xff0c;如下图所示&#xff0c;最新版本 当我参照如下搜索的内容去集成mybatis的时候&#xff0c;会出现各种各样的报错 最根本的原因是搜出来的配置是参照springboot2.X版本&#xff0c;当我们使用springboot3.x版本之后&#xff0c;需要配…

图论篇--代码随想录算法训练营第五十八天打卡|拓扑排序,dijkstra(朴素版),dijkstra(堆优化版)精讲

拓扑排序 题目链接&#xff1a;117. 软件构建 题目描述&#xff1a; 某个大型软件项目的构建系统拥有 N 个文件&#xff0c;文件编号从 0 到 N - 1&#xff0c;在这些文件中&#xff0c;某些文件依赖于其他文件的内容&#xff0c;这意味着如果文件 A 依赖于文件 B&#xff0…

分布式中间件-分布式代理框架Codis和Twemproxy

文章目录 Codis框架架构图 Twemproxy框架Codis和Twemproxy对比设计目标功能特性使用场景结论 Codis框架 Codis是一个开源的分布式内存键值存储系统&#xff0c;它基于Redis并且提供了一个分布式的解决方案来扩展单一Redis实例的能力。Codis项目由豌豆荚团队开发&#xff0c;并…

【webpack4系列】webpack构建速度和体积优化策略(五)

文章目录 速度分析&#xff1a;使用 speed-measure-webpack-plugin体积分析&#xff1a;使用webpack-bundle-analyzer使用高版本的 webpack 和 Node.js多进程/多实例构建资源并行解析可选方案使用 HappyPack 解析资源使用 thread-loader 解析资源 多进程并行压缩代码方法一&…

基于C#+Mysql实现(界面)企业的设备管理系统

管理信息系统课程设计说明书 1 引言 企业的设备管理在企业的生产制造和管理过程之中意义比较重大&#xff0c;明确企业的设备的产权和维护成本对于企业的成本控制和财务管理之中起到了重要的作用。随着市场竞争的加剧&#xff0c;现代企业所处的市场环境发生了深刻的变革&…

【Mac】系统环境配置

常用工具 Navicat PJ版本&#xff1a;this Host切换器 SwitchHosts termius 一款好用的Linux服务器连接工具&#xff1a; termius 小飞机 dddd&#xff1a;&#x1fa9c; Git mac安装git有好多种方式&#xff0c;自带的xcode或者通过Homebrew来安装&#xff0c;本文的…

Java——类型转换

一、类型转换 1、介绍 类型转换分为自动类型转换和强制类型转换。 2、自动类型转换 自动类型转换是指在表达式中&#xff0c;当两种不同的数据类型组合在一起时&#xff0c;较小的数据类型会自动转换为较大的数据类型&#xff0c;这个过程是自动的&#xff0c;无需编程者手…

清华大佬自曝:接到了省烟草局的offer,我就拒掉了华为!结果华为立马给我申请了特殊涨薪,总包70w是烟草的2倍,这可如何是好?

《网安面试指南》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484339&idx1&sn356300f169de74e7a778b04bfbbbd0ab&chksmc0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene21#wechat_redirect 《Java代码审…

C:字符串函数(续)-学习笔记

穗 一些闲话&#xff1a; 最近玩了这款饿殍-明末千里行&#xff0c;不知大家是否有听过这款游戏&#xff0c;颇有感触&#xff01;&#xff01;&#xff01; 游戏中最让我难以忘怀的便是饿殍穗线的故事&#xff0c;生在如今时代的我之前无法理解杜甫在目睹人间悲剧时的心情&…

【网络原理】❤️Tcp 连接管理机制❤️ “三次握手” “四次挥手”的深度理解, 面试最热门的话题,没有之一, 保姆式教学 !!!

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

华为 HCIP 认证费用和报名资格

在当今竞争激烈的信息技术领域&#xff0c;华为 HCIP认证备受关注。它不仅能提升个人的技术实力与职业竞争力&#xff0c;也为企业选拔优秀人才提供了重要依据。以下将详细介绍华为 HCIP 认证的费用和报名资格。 一、HCIP 认证费用 华为HCIP认证的费用主要由考试费和培训费构成…