美文网首页程序员
Spring注解——使用@Scope和@Lazy设置作用域和实现

Spring注解——使用@Scope和@Lazy设置作用域和实现

作者: 云原生实战 | 来源:发表于2018-06-22 00:07 被阅读9次

    1.默认情况下 spring 容器中都是单实例。

    import io.mieux.bean.Person;
    import io.mieux.BeanConfig;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class App03 {
        public static void main(String[] args) {
            ApplicationContext applicationContext =
                    new AnnotationConfigApplicationContext(BeanConfig.class);
            Person person1 = applicationContext.getBean(Person.class);
            Person person2 = applicationContext.getBean(Person.class);
            System.out.println(person1 == person2);
        }
    }
    

    运行结果:

    true
    

    2.如果需要多实例,则需要使用 @Scope 注解,并将其 value 设为 ConfigurableBeanFactory.SCOPE_PROTOTYPE。

    package io.mieux.config;
    
    import io.mieux.bean.Person;
    import org.springframework.beans.factory.config.ConfigurableBeanFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Scope;
    
    
    @Configuration
    public class BeanConfig {
    
        @Bean
        @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
        public Person person() {
            return new Person("zhangsan", 28);
        }
    }
    

    运行效果:

    false
    

    3.singleton 和 prototype 的实例创建的时间是不一样的。singleton 在容器初始化的时候就被创建,而 prototype 则在需要获取实例的时候才被创建。可以通过在 BeanConfig 配置类创建 Person 实例时,增加一行输出来验证。

    首先是 singleton 的验证,将 @Scope 的 value 修改为 ConfigurableBeanFactory.SCOPE_SINGLETON,并且暂时注释掉获取 person 实例部分的代码。

    package io.mieux.config;
    
    import io.mieux.bean.Person;
    import org.springframework.beans.factory.config.ConfigurableBeanFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Scope;
    
    
    @Configuration
    public class BeanConfig {
    
        @Bean
        @Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
        public Person person() {
            System.out.println("创建 Person 实例");
            return new Person("zhangsan", 28);
        }
    }
    
    import io.mieux.BeanConfig;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class App03 {
        public static void main(String[] args) {
            ApplicationContext applicationContext =
                    new AnnotationConfigApplicationContext(BeanConfig.class);
    //        Person person1 = applicationContext.getBean(Person.class);
    //        Person person2 = applicationContext.getBean(Person.class);
    //        System.out.println(person1 == person2);
        }
    }
    

    运行效果:

    创建 Person 实例
    

    接着是 prototype 的验证,将 @Scope 的 value 修改为 ConfigurableBeanFactory.SCOPE_PROTOTYPE,先依然保持注释掉获取 person 实例部分的代码。

    package io.mieux.config;
    
    import io.mieux.bean.Person;
    import org.springframework.beans.factory.config.ConfigurableBeanFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Scope;
    
    
    @Configuration
    public class BeanConfig {
    
        @Bean
        @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
        public Person person() {
            System.out.println("创建 Person 实例");
            return new Person("zhangsan", 28);
        }
    }
    

    运行之后并没有输出任何信息,说明了在容器初始化的时并没有创建实例。

    将获取 person 实例部分的代码取消注释。

    import io.mieux.config.BeanConfig;
    import io.mieux.bean.Person;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class App03 {
        public static void main(String[] args) {
            ApplicationContext applicationContext =
                    new AnnotationConfigApplicationContext(BeanConfig.class);
            Person person1 = applicationContext.getBean(Person.class);
            Person person2 = applicationContext.getBean(Person.class);
            System.out.println(person1 == person2);
        }
    }
    

    运行效果:

    创建 Person 实例
    创建 Person 实例
    false
    

    4.spring 默认使用的是 singleton,也就是刚才所说的,单实例,并且在容器初始化的时候就被创建。如果希望和 prototype 一样,在第一次使用实例时才创建,也就是常说的懒加载,就需要使用 @Lazy 注解。

    在 BeanConfig 配置类的 person 方法上增加 @Lazy 注解。

    package io.mieux.config;
    
    import io.mieux.bean.Person;
    import org.springframework.beans.factory.config.ConfigurableBeanFactory;
    import org.springframework.context.annotation.*;
    
    
    @Configuration
    public class BeanConfig {
    
        @Bean
        @Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
        @Lazy
        public Person person() {
            System.out.println("创建 Person 实例");
            return new Person("zhangsan", 28);
        }
    }
    

    先注释掉获取 person 实例部分的代码。

    import io.mieux.config.BeanConfig;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class App03 {
        public static void main(String[] args) {
            ApplicationContext applicationContext =
                    new AnnotationConfigApplicationContext(BeanConfig.class);
    //        Person person1 = applicationContext.getBean(Person.class);
    //        Person person2 = applicationContext.getBean(Person.class);
    //        System.out.println(person1 == person2);
        }
    }
    

    运行之后并没有输出任何信息,说明了在容器初始化的时并没有创建实例。

    接着取消掉获取 person1 实例的注释:

    import io.mieux.config.BeanConfig;
    import io.mieux.bean.Person;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class App03 {
        public static void main(String[] args) {
            ApplicationContext applicationContext =
                    new AnnotationConfigApplicationContext(BeanConfig.class);
            Person person1 = applicationContext.getBean(Person.class);
    //        Person person2 = applicationContext.getBean(Person.class);
    //        System.out.println(person1 == person2);
        }
    }
    

    运行效果:

    创建 Person 实例
    

    运行结果就表明了,在第一次获取 person 实例时,才会创建 person 实例。

    相关文章

      网友评论

        本文标题:Spring注解——使用@Scope和@Lazy设置作用域和实现

        本文链接:https://www.haomeiwen.com/subject/zajhyftx.html