• 3、spring注解学习(组件注册)——@Scope注解设置组件作用域、@Lazy单例对象懒加载设置


    1、spring主配置类注册一个Person组件

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.ComponentScan.Filter;
    import org.springframework.stereotype.Controller;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.FilterType;
    import org.springframework.context.annotation.Scope;
    
    import com.atguigu.bean.Person;
    
    //配置类==配置文件
    @Configuration        //告诉Spring这是一个配置类
    @ComponentScan(value="com.atguigu",        //指定要扫描的包
            excludeFilters= {@Filter(type=FilterType.ANNOTATION,classes= {Controller.class})}  //指定以某种规则排除扫描哪些组件
            /*includeFilters= {@Filter(type=FilterType.ANNOTATION,classes= {Controller.class})},    //指定以某种规则只扫描哪些组件
            useDefaultFilters = false    //includeFilters必须配合useDefaultFilters = false(默认值是true)来使用*/
            )        
    
    public class MainConfig {
        
        //给容器注册一个Bean;类型为返回值类型(bean的id默认是用方法名作为id)
        //@Bean("")增加内容后指定bean的id
        @Bean("person")
        public Person person() {
            return new Person("张三", 19);
        }
    }

    2、在测试类中写测试方法

        /**
         * 测试Scope注解设置组件作用域
         */
        @Test
        public void test02() {
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
            Person p1 = (Person) applicationContext.getBean("person");
            Person p2 = (Person) applicationContext.getBean("person");
            System.out.println(p1 == p2);
        }

    测试后输出为

     由此说明从容器中取出的Person为同一个对象,即注册的person的scope(作用域)为singleton(单例)

    spring注册的组件默认为单例模式

    3、修改主配置类person组件的作用域为prototype(多例模式)

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.ComponentScan.Filter;
    import org.springframework.stereotype.Controller;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.FilterType;
    import org.springframework.context.annotation.Scope;
    
    import com.atguigu.bean.Person;
    
    //配置类==配置文件
    @Configuration        //告诉Spring这是一个配置类
    @ComponentScan(value="com.atguigu",        //指定要扫描的包
            excludeFilters= {@Filter(type=FilterType.ANNOTATION,classes= {Controller.class})}  //指定以某种规则排除扫描哪些组件
            /*includeFilters= {@Filter(type=FilterType.ANNOTATION,classes= {Controller.class})},    //指定以某种规则只扫描哪些组件
            useDefaultFilters = false    //includeFilters必须配合useDefaultFilters = false(默认值是true)来使用*/
            )        
    
    public class MainConfig {
        
        //给容器注册一个Bean;类型为返回值类型(bean的id默认是用方法名作为id)
        //@Bean("")增加内容后指定bean的id
        @Bean("person")
        @Scope("prototype")        //多例模式
        public Person person() {
            return new Person("张三", 19);
        }
    }

    再次运行测试方法后结果为:

     则说明作用域为propotype的组件每次从容器中取出都是一个新的对象

    在注解类中设置scope也是一样的方式:

     4、单例对象懒加载设置(懒加载只针对单例对象)

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.ComponentScan.Filter;
    import org.springframework.stereotype.Controller;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.FilterType;
    import org.springframework.context.annotation.Lazy;
    import org.springframework.context.annotation.Scope;
    
    import com.atguigu.bean.Person;
    
    //配置类==配置文件
    @Configuration        //告诉Spring这是一个配置类
    @ComponentScan(value="com.atguigu",        //指定要扫描的包
            excludeFilters= {@Filter(type=FilterType.ANNOTATION,classes= {Controller.class})}  //指定以某种规则排除扫描哪些组件
            /*includeFilters= {@Filter(type=FilterType.ANNOTATION,classes= {Controller.class})},    //指定以某种规则只扫描哪些组件
            useDefaultFilters = false    //includeFilters必须配合useDefaultFilters = false(默认值是true)来使用*/
            )        
    
    public class MainConfig {
        
        //给容器注册一个Bean;类型为返回值类型(bean的id默认是用方法名作为id)
        //@Bean("")增加内容后指定bean的id
        @Bean("person")
        @Lazy                        //单例对象懒加载,第一次获取的时候才创建,而不是IOC容器初始化时创建
        public Person person() {
            return new Person("张三", 19);
        }
    }

    总结:

      singleton :表示在spring容器中的单例,通过spring容器获得该bean时总是返回唯一的实例

        单例对象在没有设置懒加载时候是在springIOC容器创建时就创建(只创建一次)

        设置懒加载之后springIOC容器创建时不创建,而是在第一次获取该单例对象时才创建(只创建一次,懒加载只对象单例对象有效)


      prototype:表示每次获得bean都会生成一个新的对象

        多例对象是在每次获取的时候才创建
      request : 表示在一次http请求内有效(只适用于web应用)
      session : 表示在一个用户会话内有效(只适用于web应用)
      globalSession : 表示在全局会话内有效(只适用于web应用)

    在多数情况,我们只会使用singleton和prototype两种scope,如果在spring配置文件内未指定scope属性,默认为singleton。

      单例的原因有二:

        1、为了性能。

        2、不需要多例。

    多例主要用在controller中

  • 相关阅读:
    grid 布局
    mongoose
    Nestjs 上传文件
    Nestjs 设置静态文件,public
    Centos 为Nginx 搭建https
    react组件
    namecheap 添加二级域名
    electron+react
    遍历文件,读取.wxss文件,在头部添加一条注释
    react 中的绑定事件
  • 原文地址:https://www.cnblogs.com/lyh233/p/12435383.html
Copyright © 2020-2023  润新知