SpringBoot @Import注解 使用
作用
一句话概括:向Spring注入Bean。
三种使用方式
- 导入普通的 Java 类
- 自定义的 ImportSelector
- ImportBeanDefinitionRegistrar
导入普通的java类
import + Configuration 实现注入
还是请我们的User.java 出场吧,定一个User类
public class User {
}
定义UserConfig.java
@Import({User.class})
@Configuration
public class UserConfig {
}
测试
依旧还是修改启动类的代码,通过上下文去获取,这里是根据类型去获取的哈,通过名称的话是获取不到的,不知道注入的bean的名称。
@SpringBootApplication
public class BootImportsApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(BootImportsApplication.class, args);
Object user = context.getBean(User.class);
System.out.println(user);
}
}
输出结果:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.1.RELEASE)
2023-07-03 14:00:34.105 INFO 14848 --- [ main] xx.imports.BootImportsApplication : Starting BootImportsApplication on ZJZL-20210402GJ with PID 14848 (F:\idea-project\xy-integration-middleware\boot\boot-imports\target\classes started by Administrator in F:\idea-project\xy-integration-middleware)
2023-07-03 14:00:34.118 INFO 14848 --- [ main] xx.imports.BootImportsApplication : No active profile set, falling back to default profiles: default
2023-07-03 14:00:35.511 INFO 14848 --- [ main] xx.imports.BootImportsApplication : Started BootImportsApplication in 2.592 seconds (JVM running for 5.809)
xx.imports.entity.User@3a0807b7
自定义的注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({User.class})
public @interface EnableUser {
}
注意:刚才新建的UserConfig 要注释掉哦。
修改启动类
在启动类上加上注解 @EnableUser
@EnableUser
@SpringBootApplication
public class BootImportsApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(BootImportsApplication.class, args);
Object user = context.getBean(User.class);
System.out.println(user);
}
}
测试
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.1.RELEASE)
2023-07-03 14:16:54.817 INFO 9640 --- [ main] xx.imports.BootImportsApplication : Starting BootImportsApplication on ZJZL-20210402GJ with PID 9640 (F:\idea-project\xy-integration-middleware\boot\boot-imports\target\classes started by Administrator in F:\idea-project\xy-integration-middleware)
2023-07-03 14:16:54.828 INFO 9640 --- [ main] xx.imports.BootImportsApplication : No active profile set, falling back to default profiles: default
2023-07-03 14:16:55.918 INFO 9640 --- [ main] xx.imports.BootImportsApplication : Started BootImportsApplication in 1.957 seconds (JVM running for 7.231)
xx.imports.entity.User@3174cb09
ImportSelector
如果定义太多注解,那么在main方法上要添加太多注解…因此使用ImportSelector ,ImportSelector 是一个接口,
该接口中只有一个 selectImports 方法,用于返回全类名数组。所以利用该特性我们可以给容器动态导入 N 个 Bean。
因为这两个bean都是通过@Enable类型注解来将配置类注册到IOC容器中,所以我们现在要做的就是将这两个bean一次性都注册到IOC容器中。
在Spring中,要将多个类进行注册,可以使用selector的方式。
新建Role.java
由于需要多个类注入,我们新建一个Role类
public class Role {
}
新建一个ApplicationSelector.java
用来返回多个类名数组
public class ApplicationSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{
User.class.getName(),
Role.class.getName()
};
}
}
定义EnableApplicationSelector 注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({ApplicationSelector.class})
public @interface EnableApplicationSelector {
}
注意:这里需要将之前定义的 UserConfig、 EnableUser注释掉哦。
修改启动类
@EnableApplicationSelector
@SpringBootApplication
public class BootImportsApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(BootImportsApplication.class, args);
Object user = context.getBean(User.class);
System.out.println(user);
Object role = context.getBean(Role.class);
System.out.println(role);
}
}
测试
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.1.RELEASE)
2023-07-03 14:27:08.124 INFO 14616 --- [ main] xx.imports.BootImportsApplication : Starting BootImportsApplication on ZJZL-20210402GJ with PID 14616 (F:\idea-project\xy-integration-middleware\boot\boot-imports\target\classes started by Administrator in F:\idea-project\xy-integration-middleware)
2023-07-03 14:27:08.135 INFO 14616 --- [ main] xx.imports.BootImportsApplication : No active profile set, falling back to default profiles: default
2023-07-03 14:27:09.219 INFO 14616 --- [ main] xx.imports.BootImportsApplication : Started BootImportsApplication in 2.336 seconds (JVM running for 6.605)
xx.imports.entity.User@42a9a63e
xx.imports.entity.Role@62da83ed
ImportBeanDefinitionRegistrar
ImportBeanDefinitionRegistrar 是一个接口,它可以手动注册bean到容器中,从而可以对类进行个性化的定制。
新建 EImportBeanDefinitionRegistrar
实现ImportBeanDefinitionRegistrar接口,并实现其中的方法
public class EImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(User.class);
// 注册一个名字叫做 halo 的 bean
beanDefinitionRegistry.registerBeanDefinition("haloUser", rootBeanDefinition);
}
}
新建 EImportUserConfig.java
@Import({EImportBeanDefinitionRegistrar.class})
@Configuration
public class EImportUserConfig {
}
修改一下启动类
这里我们通过bean的名称获取
@SpringBootApplication
public class BootImportsApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(BootImportsApplication.class, args);
Object user = context.getBean("haloUser");
System.out.println(user);
}
}
测试
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.1.RELEASE)
2023-07-03 14:32:20.845 INFO 2564 --- [ main] xx.imports.BootImportsApplication : Starting BootImportsApplication on ZJZL-20210402GJ with PID 2564 (F:\idea-project\xy-integration-middleware\boot\boot-imports\target\classes started by Administrator in F:\idea-project\xy-integration-middleware)
2023-07-03 14:32:20.860 INFO 2564 --- [ main] xx.imports.BootImportsApplication : No active profile set, falling back to default profiles: default
2023-07-03 14:32:22.476 INFO 2564 --- [ main] xx.imports.BootImportsApplication : Started BootImportsApplication in 2.949 seconds (JVM running for 7.532)
xx.imports.entity.User@5a4bef8
最后
大家如果觉得写的还不错的话,麻烦大家点个小爱心哦。