Spring注解编程(三)---注解配置给IOC容器添加组件方式

1.@Configuration&@Bean给容器中注册组件

//配置类==配置文件
@Configuration  //告诉Spring这是一个配置类
public class MainConfig {

   //给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
   @Bean("person")
   public Person person01(){
      return new Person("lisi", 20);
   }

}

2.@ComponentScan-自动扫描组件

这个就是类似在xml文件中添加的扫描的注解

@ComponentScan("com.lemon.bean")
@Configuration
public class MainConfig {


}

@Component   将当前类声明为IOC容器中的一个普通的组件(除了下面三种外的组件)
@Controller   将当前类声明为IOC容器中的一个控制器组件
@Service    将当前类声明为IOC容器中的业务逻辑层组件
@Repository    将当前类声明为IOC容器中的一个持久化层组件

@ComponentScan指定的包路径下标注了以上注解的组件都会添加到IOC容器中

3.@Conditional-按照条件注册

Conditional注解在springBoot底层中大量用到的注解,非常的重要,了解这个注解对理解SpringBoot自动装配原理会更深,下面是实现一个如果操作系统时Linux时就添加person实例到容器

@Configuration  //告诉Spring这是一个配置类
public class MainConfig {

   @Conditional(LinuxCondition.class)
   @Bean("linus")
   public Person person02(){
      return new Person("linus", 48);
   }

}
public class LinuxCondition implements Condition {


   @Override
   public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

      ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();

      ClassLoader classLoader = context.getClassLoader();

      Environment environment = context.getEnvironment();

      BeanDefinitionRegistry registry = context.getRegistry();

      String property = environment.getProperty("os.name");

      boolean definition = registry.containsBeanDefinition("person");
      if(property.contains("linux")){
         return true;
      }

      return false;
   }

}

4.@Import-给容器中快速导入一个组件

@Import快速给容器添加组件有三种方式 

@Import({Color.class,Red.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
public class MainConfig2 {
   
}

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

如上直接添加Color.class,Red.class

2)、实现ImportSelector:返回需要导入的组件的全类名数组

public class MyImportSelector implements ImportSelector {

   //返回值,就是到导入到容器中的组件全类名
   //AnnotationMetadata:当前标注@Import注解的类的所有注解信息
   @Override
   public String[] selectImports(AnnotationMetadata importingClassMetadata) {
      // TODO Auto-generated method stub
      //importingClassMetadata
      //方法不要返回null值
      return new String[]{"com.lemon.bean.Blue","com.lemon.bean.Yellow"};
   }

}

方法不能返回null 否则会报空指针异常错误

3)、实现ImportBeanDefinitionRegistrar接口:手动注册bean到容器中

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

   /**
    * AnnotationMetadata:当前类的注解信息
    * BeanDefinitionRegistry:BeanDefinition注册类;
    *        把所有需要添加到容器中的bean;调用
    *        BeanDefinitionRegistry.registerBeanDefinition手工注册进来
    */
   @Override
   public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

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

}

5.实现FactoryBean接口注册组件

//创建一个Spring定义的FactoryBean
public class ColorFactoryBean implements FactoryBean<Color> {

   //返回一个Color对象,这个对象会添加到容器中
   public Color getObject() throws Exception {
      // TODO Auto-generated method stub
      System.out.println("ColorFactoryBean...getObject...");
      return new Color();
   }

   // 返回组件类型
   public Class<?> getObjectType() {
      // TODO Auto-generated method stub
      return Color.class;
   }

   //是单例?
   //true:这个bean是单实例,在容器中保存一份
   //false:多实例,每次获取都会创建一个新的bean;
   public boolean isSingleton() {
      // TODO Auto-generated method stub
      return true;
   }

}

注意:1)、默认获取到的是工厂bean调用getObject创建的对象
          2)、要获取工厂Bean本身,我们需要给id前面加一个&,  比如: &colorFactoryBean

//工厂Bean获取的是调用getObject创建的对象
Object bean2 = applicationContext.getBean("colorFactoryBean");
Object bean3 = applicationContext.getBean("colorFactoryBean");
System.out.println("bean的类型:"+bean2.getClass());
System.out.println(bean2 == bean3);

Object bean4 = applicationContext.getBean("&colorFactoryBean");
System.out.println(bean4.getClass());

猜你喜欢

转载自my.oschina.net/u/3737136/blog/1927261
今日推荐