【Spring Boot】SpringBoot自动装配-Import

06-01 1127阅读

目录

    • 一、前言
    • 二、 定义
    • 三、使用说明
      • 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注解
                        • 七、小结

                          【Spring Boot】SpringBoot自动装配-Import

                          【Spring Boot】SpringBoot自动装配-Import

                          一、前言

                          @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 创建项目

                          【Spring Boot】SpringBoot自动装配-Import

                          3.1.1 导入依赖

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

                          
                              4.0.0
                              
                                  org.springframework.boot
                                  spring-boot-starter-parent
                                  2.5.3
                                   
                              
                              com.ldx
                              import-annotation
                              0.0.1-SNAPSHOT
                              import-annotation
                              Demo project for Spring Boot
                              
                                  1.8
                              
                              
                                  
                                      org.springframework.boot
                                      spring-boot-starter
                                  
                                  
                                      org.projectlombok
                                      lombok
                                      true
                                  
                              
                              
                                  
                                      
                                          org.springframework.boot
                                          spring-boot-maven-plugin
                                          
                                              
                                                  
                                                      org.projectlombok
                                                      lombok
                                                  
                                              
                                          
                                      
                                  
                              
                          
                          
                          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 {
                             @Bean
                             public 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 {
                             @Override
                             public 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 {
                             @Override
                             public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
                                // 创建User类型的Bean的定义
                                BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
                                // 将创建的UserBean定义注册到SpringRegistry中,其名称为user
                                registry.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 导入依赖

                          没啥特别的依赖

                          
                             4.0.0
                             
                                org.springframework.boot
                                spring-boot-starter-parent
                                2.5.3
                                 
                             
                             com.ldx
                             user
                             0.0.1-SNAPSHOT
                             user
                             Demo project for Spring Boot
                             
                                1.8
                             
                             
                                
                                   org.springframework.boot
                                   spring-boot-starter
                                
                                
                                   org.projectlombok
                                   lombok
                                   true
                                
                             
                             
                                
                                   
                                      org.springframework.boot
                                      spring-boot-maven-plugin
                                      
                                         
                                            
                                               org.projectlombok
                                               lombok
                                            
                                         
                                      
                                   
                                
                             
                          
                          
                          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 getTeachers() {
                                List 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)
                              );
                            }
                            @Bean
                            public User getUser() {
                              return new User();
                            }
                          }
                          

                          5.3 创建book-manage模块

                          5.3.1 导入依赖
                          
                             4.0.0
                             
                                org.springframework.boot
                                spring-boot-starter-parent
                                2.5.3
                                 
                             
                             com.ldx
                             book-manage
                             0.0.1-SNAPSHOT
                             book-manage
                             Demo project for Spring Boot
                             
                                1.8
                             
                             
                                
                                   org.springframework.boot
                                   spring-boot-starter
                                
                                
                                   org.projectlombok
                                   lombok
                                   true
                                
                                
                                
                                   com.ldx
                                   user
                                   0.0.1-SNAPSHOT
                                
                             
                             
                                
                                   
                                      org.springframework.boot
                                      spring-boot-maven-plugin
                                      
                                         
                                            
                                               org.projectlombok
                                               lombok
                                            
                                         
                                      
                                   
                                
                             
                          
                          
                          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配置

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码