← 返回首页
Spring基础教程(八)
发表时间:2020-05-12 18:28:40
讲解@Scope注解

Scope,也称作用域,在Spring Ioc容器指其创建的Bean对象对其他Bean对象的请求可见范围,在Spring IoC 容器中具有以下几种作用域,基本作用域(singleton,prototype),web作用域(request,session,globalsession),自定义作用域。

常见作用域见下表: |作用域|描述| |-|-| |singleton|单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例| |prototype|原型模式,每次通过容器getBean方法获取protetype定义bean,都将产生一个新的bean实例| |request|对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效| |session|对于每次HTTP Session,使用session定义的Bean都将产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效| |globalsession|每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效|

实例

在上节的基础上,我们测试@Scope注解的用法。 改写SpringConfiguration配置类,在public Person getPerson()方法上添加@Scope注解。

package com.config;

import com.entity.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
@ComponentScan(basePackages = "com")
public class SpringConfiguration {

    @Bean(name = {"p1","person"})
    @Scope("singleton") // 等同于@Scope,默认是singleton
    public Person getPerson(){
        return new Person("zhangsan","男",20);
    }

}

改写测试类,从IOC容器中连续两次获取p1对象。测试是否单例。

package com.test;

import com.config.SpringConfiguration;
import com.entity.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringDemo {

    public static void main(String[] args) {

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfiguration.class);
        Person person1 = (Person) context.getBean("p1");
        Person person2 = (Person) context.getBean("p1");
        System.out.println(person1==person2);

    }

}

运行结果:
true

将@Scope值改为"prototype"原型模式,测试是否单例。

package com.config;

import com.entity.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
@ComponentScan(basePackages = "com")
public class SpringConfiguration {

    @Bean(name = {"p1","person"})
    @Scope("prototype" ) 
    public Person getPerson(){
        return new Person("zhangsan","男",20);
    }

}

运行测试类:

package com.test;

import com.config.SpringConfiguration;
import com.entity.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringDemo {

    public static void main(String[] args) {

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfiguration.class);
        Person person1 = (Person) context.getBean("p1");
        Person person2 = (Person) context.getBean("p1");
        System.out.println(person1==person2);

    }

}

运行结果:
false

如果使用XML方式,scope属性使用方式如下:

    <bean class="com.entity.Person" name="p1,person" scope="prototype">
         <property name="name" value="zhangsan"/>
         <property name="gender" value="男"/>
         <property name="age" value="20"/>
         <property name="car" ref="car"/>
     </bean>