Spring Boot自动装配机制中的@Import用法
简介
@Import注解用于将其他类加载到Spring的IOC容器中,支持四种主要用法:
- 直接导入Bean类
- 导入配置类
- 导入实现ImportSelector接口的类
- 导入实现ImportBeanDefinitionRegistrar接口的类
定义
@Import注解的定义如下,其参数为一个Class数组:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
Class>[] value();
}
使用示例
创建项目
在Maven项目中添加Spring Boot和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/>
</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>
创建User类
package com.ldx.importannotation;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class User {
public User() {
this.name = "李四";
this.age = 13;
}
private String name;
private Integer age;
}
测试导入Bean
在启动类上使用@Import注解导入User类。
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 = 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);
}
}
测试导入配置类
创建一个配置类并使用@Import导入。
public class UserConfig {
@Bean
public User getUser(){
return new User();
}
}
修改启动类的@Import值为UserConfig类。
测试导入ImportSelector
创建一个实现ImportSelector接口的类,并在启动类中使用@Import导入该类。
public class UseImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.ldx.importannotation.User"};
}
}
测试导入ImportBeanDefinitionRegistrar
创建一个实现ImportBeanDefinitionRegistrar接口的类,并在启动类中使用@Import导入该类。
public class UserImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
registry.registerBeanDefinition("user", beanDefinition);
}
}
改进
创建一个自定义注解来简化导入过程。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(UseImportSelector.class)
public @interface EnableUser {}
在启动类中使用@EnableUser注解代替@Import。
验证
创建两个模块,一个提供Bean,另一个通过引入Jar包来验证是否能直接使用Bean。
在user模块中创建User类和启动类,确保能够正确获取Bean。
在book-manage模块中添加对user模块的依赖,并尝试获取User Bean。
结论
通过@Import可以灵活地将Bean或配置类加载到Spring容器中。对于第三方库,可以通过自定义注解进一步优化使用方式。