三、Spring的@Scope设置组件作用域

还是和上节一样,首先来看下配置类:MainConfig2

@Configuration
名
public class MainConfig2 {

    @Scope("singleton") // 默认就是单实例的
    @Bean("person")
    public Person person(){
        System.out.println("给容器中添加Person....");
        return new Person("张三", 25);
    }
}   

再看下person室实体类:

public class Person {

    private String name;
    private Integer age;
    private String nickName;
    // 省略...
}

我们知道,在spring中bean默认是单实例的,所以@Scope("singleton")都一样,我们写个测试类测试一下

    @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);
    }

打印一下:

给容器中添加Person.... // 容器在一启动的时候便创建好了bean
mainConfig2 // 配置类本身也是bean
person

以上结果可以看出:

容器在一启动的时候便创建好了bean

我们再将注释放开

    @Test
    public void test02(){
        System.out.println("ioc容器创建完成....");
        Object bean = applicationContext.getBean("person");
        Object bean2 = applicationContext.getBean("person");
        System.out.println(bean == bean2);
    }

打印一下:

给容器中添加Person....
ioc容器创建完成....
true

可以得出,结果为true,说明两次获取的bean是一样的,证明了默认是单实例的,


其他保持不变,将@Scope("singleton")替换成@Scope("prototype")

执行下第一个测试方法:

mainConfig2 
person

发现容器并没有创建,说明prototype作用域下,spring的bean不是随容器启动而创建的

再次执行两个两个测试方法:

    @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);
    }

打印结果:

mainConfig2 
person
ioc容器创建完成....
给容器中添加Person....
给容器中添加Person....
false

观察结果说明:获取bean的时候,才动态的创建了bean,并且两个bean不相等,也说明了此时bean是多实例的,自然不相等。


另外其实spring中bean的作用域不止这两种,

spring官方文档描述如下:前两种比较常用,后面的几种几乎用不上

@Scope:调整作用域
prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。
                    每次获取的时候才会调用方法创建对象;
singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。
            以后每次获取就是直接从容器(map.get())中拿,
request:同一次请求创建一个实例
session:同一个session创建一个实例

另外还有需要一提的是,,如果想要单实例,在ioc容器创建的时候不加载,而是在第一次使用bean的时候才加载,可以使用@Lazy注解,加在配置类中创建bean的方法上,加了这个注解后,对于单实例,只会在第一次使用bean的时候加载bean
加油,晚安!

猜你喜欢

转载自www.cnblogs.com/heliusKing/p/11361221.html
今日推荐