1.Spring容器加入对象方式简介
- 使用XML配置文件
- 在XML配置文件中使用< bean >标签来定义Bean,通过ClassPathXmlApplicationContext等容器来加载并初始化Bean。
使用注解
使用Spring提供的注解,例如@Component、@Service、@Controller、@Repository等注解来标识Bean
然后通过@ComponentScan等注解扫描器来加载并初始化Bean。
使用Java配置
可以使用Java代码来配置Bean,例如使用@Configuration和@Bean注解来定义Bean
然后通过AnnotationConfigApplicationContext等容器来加载并初始化Bean。
使用Import注解
使用@Import注解来引入其他配置类,然后通过容器加载并初始化Bean
@Import注解提供了三种用法
直接Import导入
ImportSelector接口批量
ImportBeanDefinitionRegistrar条件注册
2.import注解导入Bean实操
(1)import注解简介
- import注解是Spring框架中的一个注解,用于在一个配置类中引入其他配置类或者普通的Java类
- 通过@Import注解,可以将其他配置类或者Java类中定义的Bean引入到当前配置类中
- 默认的bean名称是【类全限定名,即包名+类名】
- (2)import注解源码
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Import { Class<?>[] value(); }
- 创建汽车相关的接口以及类实体Bean
//汽车接口 public interface Car { } //奔驰类 @Data @NoArgsConstructor @AllArgsConstructor public class BenChiCar implements Car{ private String name = "奔驰汽车"; } //宝马类 @Data @NoArgsConstructor @AllArgsConstructor public class BaoMaCar implements Car{ private String name = "宝马汽车"; } //奥迪类 @Data @NoArgsConstructor @AllArgsConstructor public class AoDiCar implements Car{ private String name = "奥迪汽车"; }
- 创建配置类Manager
@Configuration @Import(value = {BaoMaCar.class, AoDiCar.class, BenChiCar.class}) public class CarBeanManager { }
- 主类测试
public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); //扫描指定的包,包括子包 context.scan("com.lixiang"); //里面完成初始化操作,核心方法 context.refresh(); Map<String, Car> beansOfType = context.getBeansOfType(Car.class); beansOfType.forEach((k,v)-> System.out.println(k+"="+v)); } }
3.ImportSelector批量导入Bean实操
(1)importSelector批量导入简介
- ImportSelector 接口用于实现动态注册Bean的功能,【批量】导入对象到容器里,根据条件动态地选择需要注册的Bean,并加入Spring容器
- 实现ImportSelector接口,这个接口的selectImports方法会返回一个String数组,数组中的值就是要添加的组件的全类名
(2)importSelector源码
public interface ImportSelector { //该方法的返回值是一个String数组,用于指定需要注册的Bean的类名。 String[] selectImports(AnnotationMetadata importingClassMetadata); @Nullable default Predicate<String> getExclusionFilter() { return null; } }
(3)案例实战
- 我们还是用Car这几个实体Bean,批量导入到Spring容器,自定义选择器实现ImportSelector接口。
public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[] {"com.lixiang.domain.AoDiCar","com.lixiang.domain.BaoMaCar","com.lixiang.domain.BenChiCar"}; } }
- 在我们的Manager中修改import值
@Configuration //只需要引入MyImportSelector即可 @Import(value = {MyImportSelector.class}) public class CarBeanManager { }
- 主类测试
public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); //扫描指定的包,包括子包 context.scan("com.lixiang"); //里面完成初始化操作,核心方法 context.refresh(); Map<String, Car> beansOfType = context.getBeansOfType(Car.class); beansOfType.forEach((k,v)-> System.out.println(k+"="+v)); } }
4.BeanDefinitionRegistrar动态注册Bean实操
(1)ImportBeanDefinitionRegistrar接口简介
ImportBeanDefinitionRegistrar是Spring框架中的一个接口,用于实现动态注册Bean的功能
ImportBeanDefinitionRegistrar可以在运行时动态地向Spring容器中注册BeanDefinition
与ImportSelector不同的是,ImportSelector只能返回需要注册的Bean的类名
在使用@Import注解时,将实现ImportBeanDefinitionRegistrar接口的类引入到当前配置类中,实现动态注册Bean的功能
(2)ImportBeanDefinitionRegistrar源码
public interface ImportBeanDefinitionRegistrar { /** * @param importBeanNameGenerator * @param annotationMetadata 当前类的注解相关信息 * @param registry IOC容器里面bean的注册信息 */ default void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) { registerBeanDefinitions(importingClassMetadata, registry); } /** * @param annotationMetadata 当前类的注解相关信息 * @param registry IOC容器里面bean的注册信息 */ default void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { } }
(3)案例实战
- 现在我们有一个场景,当宝马汽车、奥迪汽车、奔驰汽车都存在时,新创建一个新能源汽车
- 创建新能源汽车主类
@Data @NoArgsConstructor @AllArgsConstructor public class NewEnergyCar implements Car{ private String name = "新能源汽车"; }
- 创建自定义的ImportBeanDefinitionRegistrar
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) { /** * 可以通过该方法进行手动注册 */ boolean adCar = beanDefinitionRegistry.containsBeanDefinition("com.lixiang.domain.AoDiCar"); boolean bmCar = beanDefinitionRegistry.containsBeanDefinition("com.lixiang.domain.BaoMaCar"); boolean bcCar = beanDefinitionRegistry.containsBeanDefinition("com.lixiang.domain.BenChiCar"); if (adCar && bmCar && bcCar){ //IOC容器加个混合对象 BeanDefinition beanDefinition = new RootBeanDefinition(NewEnergyCar.class); beanDefinitionRegistry.registerBeanDefinition("newEnergyCar",beanDefinition); } } }
配置Manager中import的值
@Configuration @Import(value = {MyImportSelector.class,MyImportBeanDefinitionRegistrar.class}) public class CarBeanManager { }
- 主类测试
public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); //扫描指定的包,包括子包 context.scan("com.lixiang"); //里面完成初始化操作,核心方法 context.refresh(); Map<String, Car> beansOfType = context.getBeansOfType(Car.class); beansOfType.forEach((k,v)-> System.out.println(k+"="+v)); } }
(4)BeanDefinition 介绍
- Spring容器中最重要的概念之一,它是容器创建和管理Bean实例的基础,对Bean的定义信息的抽象和封装
- 描述一个Bean的定义信息,包括Bean的名称、类型、作用域、属性等信息
- 可以对Bean的创建和管理进行详细的配置和控制,例如可以指定Bean的作用域、是否懒加载、是否自动注入等属性