介绍
@Scope 注解用于指定作用范围
源码
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Scope {
@AliasFor("scopeName")
String value() default "";
@AliasFor("value")
String scopeName() default "";
ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;
}
使用
搭配 @Controller、@Service、@Repository、@Component 、@Bean 使用,修饰类
属性
value 取值如下:
singleton:单例模式,默认值(最常用)
prototype:多例。每次都创建一个新对象(较常用)
- request:用于web项目,当有新的Http请求时,就会创建一个新对象,在该请求期间,是单例的
- session:用于web项目,当有新的Http session时,就会创建一个新对象,在当前session期间,是单例的
- global-session:用于web项目,应用在集群,全局session。
不是集群时,功能同session。
singleton
单例模式,默认值(最常用)
生命周期:
- 创建:spring容器创建时,就开始创建该对象
- 生存:只要容器在,对象一直活着
- 死亡:容器销毁时,对象就销毁了
例子
修改Controller,再增加一个 IStudentService 成员变量
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@Scope("prototype")
public class StudentCtrl {
@Resource
private StudentSrvImpl studentSrv;
@Autowired
private StudentSrvImpl studentSrv2;
@Autowired
public StudentCtrl(){
System.out.println("StudentCtrl()构造方法");
}
@RequestMapping("/test")
public String test( ){
// System.out.println(student);
System.out.println(studentSrv);
System.out.println(studentSrv2);
System.out.println(studentSrv==studentSrv2);
return "保存成功!";
}
}
访问该 Controller,打印 studentSrv 和 studentSrv2 的内存地址,是一样的,而且打印 true
prototype
多例。每次都创建一个新对象(较常用)
生命周期:
- 创建:当使用对象时,创建新的对象实例。
- 生存:只要对象在使用中,就一直活着。
- 死亡:由 java 垃圾回收器回收
例子
在上面例子基础之上,继续修改 StudentSrvImpl,增加 @Scope("prototype") 注解
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@Scope("prototype")
public class StudentSrvImpl {
public StudentSrvImpl(){
System.out.println("StudentSrvImpl构造方法:"+this);
}
public List query() {
System.out.println("调用 StudentSrvImpl 的query()方法");
return null;
}
public void save(){
System.out.println("调用 StudentSrvImpl 的save()方法");
}
}
访问 Controller,打印 studentSrv 和 studentSrv2 的内存地址,可以看出2个对象的 内存地址不同,并且是false,说明创建了2个对象