springBoot容器中注册组件

1. @Bean

用于配置对象让 spring 来创建的。

默认情况下它调用的是类中的无参构造函数。如果没有无参构造函数则不能创建功。

1.1. 属性

  1. id:给对象在容器中提供一个唯一标识。用于获取对象。
  2. class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。
  3. init-method:指定类中的初始化方法名称。
  4. destroy-method:指定类中销毁方法名称。

1.2. 生命周期

scope:指定对象的作用范围。

1.2.1. singleton 默认值

  1. IoC容器中仅存在一个Bean实例,Bean以单例方式存在,
  2. 一个应用只有一个对象的实例。它的作用范围就是整个引用
  3. 对象出生:当应用加载,创建容器时,对象就被创建了。
  4. 对象活着:只要容器在,对象一直活着。
  5. 对象死亡:当应用卸载,销毁容器时,对象就被销毁了

1.2.2. prototype

  1. 每次从容器中调用Bean时,都返回一个新的实例
  2. 即每次调用getBean()时相当于执行new XxxBean(),不会初始化,只用在使用的时候
  3. 对象出生:当使用对象时,创建新的对象实例。
  4. 对象活着:只要对象在使用中,就一直活着。
  5. 对象死亡:当对象长时间不用时,被java的垃圾回收器回收了

1.2.3. request

每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境

1.2.4. session

同一个HTTP Session 共享一个Bean,不同Session使用不同Bean,仅适用于WebApplicationContext环境

1.2.5. globalSession

一般用于Portlet应用环境,该作用域仅适用于WebApplicationContext 环境

1.3. init-method destroy-method

@Configuration
@ComponentScan("com.du")
public class BeanOfLifeCycle {
    @Bean(initMethod="init",destroyMethod="detory")
    public Car car(){
        return  new Car();
    }
}
@Component
public class Car {
   public Car(){
      System.out.println("car constructor...");
   }
   public void init(){
      System.out.println("car ... init...");
   }
   public void detory(){
      System.out.println("car ... detory...");
   }
}

@Bean和@Qualifier 结合使用 

当需要在Spring应用中通过@Bean注解创建多个相同类型的bean实例,并且希望在依赖注入时能够精确地选择这些实例中的某一个时,@Qualifier注解就显得尤为重要了。下面是如何结合@Bean和@Qualifier来生成并注入多个相同类型的bean实例的示例:

创建多个bean实例

首先,在配置类中使用@Bean注解创建多个相同类型的bean,但为每个bean分配不同的名称(通过方法名或直接使用@Qualifier注解指定)

 

@Configuration
public class AppConfig {

    @Bean
    @Qualifier("serviceInstance1")
    public MyService createServiceInstance1() {
        return new MyServiceImpl("Instance 1 Config");
    }

    @Bean
    @Qualifier("serviceInstance2")
    public MyService createServiceInstance2() {
        return new MyServiceImpl("Instance 2 Config");
    }
}
@Service
public class SomeClientService {

    private final MyService serviceInstance1;
    private final MyService serviceInstance2;

    @Autowired
    public SomeClientService(
            @Qualifier("serviceInstance1") MyService service1,
            @Qualifier("serviceInstance2") MyService service2) {
        this.serviceInstance1 = service1;
        this.serviceInstance2 = service2;
    }
    // ...
}

2. @Component

Controller 一般用于表现层的注解。

Service 一般用于业务层的注解。

Repository 一般用于持久层的注解。

@Component类中的@Bean注解的方法,返回的是一个新的实例。

@Component注解并没有通过 cglib 来代理@Bean 方法的调用,因此像下面这样配置时,就是两个不同的country

@Component
public class MyBeanConfig {

    @Bean
    public Country country(){
        return new Country();
    }

    @Bean
    public UserInfo userInfo(){
        return new UserInfo(country());
    }

}

有些特殊情况下,我们不希望MyBeanConfig被代理(代理后会变成WebMvcConfig$$EnhancerBySpringCGLIB$$8bef3235293)时,就得用@Component,这种情况下,上面的写法就需要改成下面这样:

@Component
public class MyBeanConfig {

    @Autowired
    private Country country;

    @Bean
    public Country country(){
        return new Country();
    }

    @Bean
    public UserInfo userInfo(){
        return new UserInfo(country);
    }
}

3. @Import

用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration 注解

3.1. 实现 ImportSelector :返回需要导入的组件的全类名数组

public class MyImportSelect implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.du.domain.Blue","com.du.domain.Yellow"};
    }
}

3.2. 实现 ImportBeanDefinitionRegistrar:手动注册bean到容器中

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
  @Override
  public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
                                      BeanDefinitionRegistry registry) {

    boolean definition = registry.containsBeanDefinition("com.du.domain.Yellow");
    boolean definition2 = registry.containsBeanDefinition("com.du.domain.Blue");
    if(definition && definition2){
      //指定Bean定义信息;(Bean的类型,Bean。。。)
      RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
      //注册一个Bean,指定bean名
      registry.registerBeanDefinition("rainBow", beanDefinition);
    }
  }
}

3.3. @Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名

利用 car的无参构造器

@Configuration
@Import({Car.class,MyImportSelect.class,MyImportBeanDefinitionRegistrar.class})
public class ImportShow {
}

3.4. 测试

AnnotationConfigApplicationContext applicationContext =
        new AnnotationConfigApplicationContext(ImportShow.class);
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
    System.out.println(beanDefinitionName);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值