 
     
本文包含以下内容:
- 
使用@Scope指定作用域测试 
- 
使用@Lazy 配置懒加载测试 
- 
使用@Conditional根据条件创建实例测试 
- 
拓展@Scope、@Lazy、@Conditional 
1.使用@Scope指定作用域测试
      1)默认情况下,Spring 创建实例的作用域是
      
       单例的
      
      ,通过一下测试得到结论:
     
@Test  public void test02(){    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);//    String[] definitionNames = applicationContext.getBeanDefinitionNames();//    for (String name : definitionNames) {//      System.out.println(name);//    }//        System.out.println("ioc容器创建完成....");    Object bean = applicationContext.getBean("person");    Object bean2 = applicationContext.getBean("person");    System.out.println(bean == bean2);  }运行结果,如下图所示:
       
     
     2)使用
  @Scope
  ()修改
     
      作用域
     
     ,作用域可用参数
     
      prototype:
     
     多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。每次获取的时候才会调用方法创建对象;
     
      singleton:
     
     单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。以后每次获取就是直接从
     
      容器
     
     (map.get())中拿,
     
      request:
     
     同一次请求创建一个实例
     
      session:
     
     同一个session创建一个实例
将创建实例的方法上添加上@Scope(“prototype”) 表示多实例的
@Scope("prototype")  @Bean("person")  public Person person01(){    return new Person("张三", 25);  }再次运行得到结果如下
       
     
2.使用@Lazy 配置懒加载测试
     在默认的作用域为单例的模式下,可以使用
  @Lazy 进行懒加载,即调用的时候,再创建实例对象
  @Lazy  @Bean("person")  public Person person01(){    System.out.println("给容器中添加Person....");    return new Person("张三", 25);  }配置懒加载前:
       
     
配置懒加载后:
       
     
3.使用@Conditional根据条件创建实例测试
     可以通过@Conditional 判断时候满足对应条件再进行创建,即如果要判断当前运行系统来创建指定的Bean 。1)创建
  Condition 接口的实现类,作为判断条件的类:
//判断是否windows系统public class WindowsCondition implements Condition {  @Override  public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {    Environment environment = context.getEnvironment();    String property = environment.getProperty("os.name");    if(property.contains("Windows")){      return true;    }    return false;  }}     创建判断Linux 系统的实现类,其中两个参数:
     
      ConditionContext
     
     :判断条件能使用的上下文(环境)如获得获得类加载器、当前环境信息、Bean注册类等信息
     
      AnnotatedTypeMetadata
     
     :注释信息
//判断是否linux系统public class LinuxCondition implements Condition {  /**   * ConditionContext:判断条件能使用的上下文(环境)   * AnnotatedTypeMetadata:注释信息   */  @Override  public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {    // TODO是否linux系统    //1、能获取到ioc使用的beanfactory    ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();    //2、获取类加载器    ClassLoader classLoader = context.getClassLoader();    //3、获取当前环境信息    Environment environment = context.getEnvironment();    //4、获取到bean定义的注册类    BeanDefinitionRegistry registry = context.getRegistry();        String property = environment.getProperty("os.name");        //可以判断容器中的bean注册情况,也可以给容器中注册bean    boolean definition = registry.containsBeanDefinition("person");    if(property.contains("linux")){      return true;    }        return false;  }}2)建立不同条件对应的Bean
  @Conditional(WindowsCondition.class)  @Bean("bill")  public Person person01(){    return new Person("Bill Gates",62);  }  @Conditional(LinuxCondition.class)  @Bean("linus")  public Person person02(){    return new Person("linus", 48);  }3)建立测试方法
@Test  public void test03(){    String[] namesForType = applicationContext.getBeanNamesForType(Person.class);    ConfigurableEnvironment environment = applicationContext.getEnvironment();    //动态获取环境变量的值;Windows 10    String property = environment.getProperty("os.name");    System.out.println(property);    for (String name : namesForType) {      System.out.println(name);    }        Map<String, Person> persons = applicationContext.getBeansOfType(Person.class);    System.out.println(persons);      }获得结果:
       
     
4)修改启动参数,模拟linux 系统启动
       
     
添加配置 -Dos.name=linux
       
     
运行结果:
       
     
5)也可以将注解放在类上,对于所有当前类下所有的@Bean 注解,满足条件才进行创建
//类中组件统一设置。满足当前条件,这个类中配置的所有bean注册才能生效;@Conditional({WindowsCondition.class})public class MainConfig2 {}4.拓展@Scope、@Lazy、@Conditional
     1)@Scope使用场景:几乎
  90%以上的业务使用singleton单实例就可以,所以spring默认的类型也是singleton,singleton虽然保证了全局是一个实例,对性能有所提高,但是如果实例中有非静态变量时,会导致线程安全问题,共享资源的竞争当设置为prototype时:每次连接请求,都会生成一个bean实例,也会导致一个问题,当请求数越多,
     
      性能会降低
     
     ,因为创建的实例,导致GC频繁,gc时长增加2)@Lazy主要作用:@Lazy注解注解的作用主要是减少springIOC容器启动的加载时间当出现循环依赖时,也可以添加@Lazy3)@Conditional
  应用场景:在一些需要条件满足才是实例化的类中,使用此注解,我曾经在项目中需要根据不同的场景使用不同的mq中间件的时候使用过,在mq的实例化bean上,加上此注解,根据配置文件的不同,来决定这个bean是否加载至ioc容器中。
      
       -END-
      
     
       
     
      
       可以关注我的公众号,免费获取价值1980元
      
      
       学习资料
      
     
      
       点击“在看”,学多少都不会忘~
      
     
      
    
 
