ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SpringBoot自动装备-Import

2021-08-01 20:34:01  阅读:191  来源: 互联网

标签:SpringBoot import springframework 自动 User org Import class


1. 简介

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

  1. 导入Bean

  2. 导入配置类

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

  4. 导入 ImportBeanDefinitionRegistrar 实现类。

2. 定义

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

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

3. 使用说明

通过一个简单的小例子测试一下@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.2.2 启动测试

UserBean注入成功。

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.3)

2021-08-01 19:36:55.243  INFO 49498 --- [           main] c.l.i.ImportAnnotationApplication        : Starting ImportAnnotationApplication using Java 1.8.0_261 on ludangxindeMacBook-Pro.local with PID 49498 (/Users/ludangxin/workspace/idea/import-annotation/target/classes started by ludangxin in /Users/ludangxin/workspace/idea/import-annotation)
2021-08-01 19:36:55.245  INFO 49498 --- [           main] c.l.i.ImportAnnotationApplication        : No active profile set, falling back to default profiles: default
2021-08-01 19:36:55.731  INFO 49498 --- [           main] c.l.i.ImportAnnotationApplication        : Started ImportAnnotationApplication in 0.893 seconds (JVM running for 1.417)
2021-08-01 19:36:55.735  INFO 49498 --- [           main] c.l.i.ImportAnnotationApplication        : user info ===User(name=李四, age=13)

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)

3.3.3 启动测试

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.5.3 启动测试

UserBean注入成功。

3.6 小结

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

好处:

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

4. 改进

上面的例子通过使用@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);
   }
}

4.3 启动测试

UserBean注入成功。

标签:SpringBoot,import,springframework,自动,User,org,Import,class
来源: https://www.cnblogs.com/ludangxin/p/15087565.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有