Spring IoC容器添加组件的方式

  小编在博文《Spring Bean是什么》中介绍了Bean的基本概念,这里详细地介绍如何注册bean。

1、包扫描@ComponentScan+组件标注注解

  适用场景:可以通过该方式把我们自己写的组件加载到容器中。使用注解@CompentScan进行包扫描,将带有@Controller、@Service、@Respository和@Compent注解的类扫描到IoC容器中。

  包扫描不是必须的,指定包名后以指定的包名为准,比如指定包名为a:@ComponentScan("a"),即使b包中有标注@Controller等注解的bean,它也不注册。包扫描注解除了默认的方法value(),还包括如下方法:
basePackages(): 指定扫描的包名(前缀)。
basePackageClasses():如果指定为A.class,那么会扫描A类所在包的类。
includeFilters():将所指定的类注入容器。
excludeFilters():将所指定的类排除。

2、通过@Bean导入组件

  适用于导入第三方组件的类。 可以放在方法和注解上,一般放在标有@Configuration类中的方法上。更多详细信息请戳我

3、通过@Import导入组件

  需要注意的是,被导入组件的ID默认是全类名。

3.1、导入类

@Configuration @Import(value = {Person.class, Car.class}) 
public class MainConfig {
}

3.2、导入ImportSeletor类实现组件

public class MyImportSelector implements ImportSelector { 
  //可以获取导入类的注解信息 
  @Override 
  public String[] selectImports(AnnotationMetadata importingClassMetadata) {
     return new String[]{"com.my.testimport.compent.Car"}; 
  } 
}

@Configuration
@Import(value = {Person.class, Car.class, MyImportSelector.class}) 
public class MainConfig {
}

  Spring Boot的自动注入就是用了这种方式。

3.3、导入实现 ImportBeanDefinitionRegister接口类的组件

public class MyBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {
  @Override 
  public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    //创建一个bean定义对象 
    RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Cat.class); 
    //把bean定义对象导入到容器中 
    registry.registerBeanDefinition("cat",rootBeanDefinition); 
  } 
}
@Configuration 
@Import(value = {Person.class, Car.class, MyImportSelector.class, MyBeanDefinitionRegister.class}) 
public class MainConfig {
}

  AOP的实现注册类AutoProxyRegistrar就是实现了ImportBeanDefinitionRegister类。

4、通过实现FacotryBean接口注册组件

@Component
public class CarFactoryBean implements FactoryBean<Car> { 
  //返回bean的对象 
  @Override
   public Car getObject() throws Exception {
    return new Car(); 
  }
  //返回bean的类型 
  @Override 
  public Class<?> getObjectType() {
    return Car.class; 
  }
  //是否为单利 
  @Override 
  public boolean isSingleton() {
    return true; 
  } 
}

  Spring获取对象时,返回的是getObject方法返回的对象,要想返回fanctoryBean对象,需要在获取对象名前加上&符号,即 getBean("carFactoryBean" )返回car对象,getBean("&carFactoryBean" )返回CarFactoryBean 对象。

public class App {
    public static void main(String[] args) {
        //读取注解
        ApplicationContext applicationContext1 = new AnnotationConfigApplicationContext(MyConfig2.class);
        String[] names=  applicationContext1.getBeanDefinitionNames();
        for (String name:names){
           System.out.println(name);  //这里输出的类的全类名
        }
    }
}

结束语

  那么大家对于这件事都是怎么看的呢?欢迎在文章下方留言讨论!三人行必有我师焉!小编每条都会仔仔细细地看。

posted @ 2022-02-09 17:17  楼兰胡杨  阅读(110)  评论(0编辑  收藏  举报