参考:@Scope注解 详细讲解及示例
官方文档
When used as a type-level annotation in conjunction with @Component, @Scope indicates the name of a scope to use for instances of the annotated type.
When used as a method-level annotation in conjunction with @Bean, @Scope indicates the name of a scope to use for the instance returned from the method.
@Scope与@Component一起在类级别上使用时,表示该类的所有实例的范围。
@Scope与@Bean一起用在方法上时,表示该方法生成的实例的范围。
@Scope表示的范围有以下几种
- singleton 单实例的(单例)(
默认:不写@Scope注解默认就是单例模式
) ----全局有且仅有一个实例 - prototype 多实例的(多例) ---- 每次获取Bean的时候会有一个新的实例
- reqeust 同一次请求 ----request:每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效
- session 同一个会话级别 ---- session:每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效
注:这边只演示我们常用的 singleton、prototype 两种,其他的可以自己试试
singleton模式下默认是饿汉模式
饿汉模式:容器启动时就会创建实例对象:
package com.xl.test.logtest.utils;
import org.springframework.stereotype.Component;
//@Component
public class Cup {
int y;
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
package com.xl.test.logtest.utils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
@Configuration
public class MyConfig {
@Bean
public Cup cupBean() {
System.out.println("默认的@Scope (singleton),饿汉模式:容器启动时就会创建对象");
return new Cup();
}
}
启动项目:
prototype默认是懒汉模式
懒汉模式:IOC容器启动的时候,并不会创建对象,而是 在第一次使用的时候才会创建
package com.xl.test.logtest.utils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
@Configuration
public class MyConfig {
@Bean
@Scope(value="prototype")
public Cup cupBean() {
System.out.println("@Scope取值为prototype时为懒汉模式,启动容器时不会创建对象。");
return new Cup();
}
}
启动项目:
调用bean对象:
@GetMapping("/log")
public String log() {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MyConfig.class);
ac.getBean(Cup.class);
ac.getBean(Cup.class);
return "autowiredTest.testA()";
}
如上,调用了两次,预期会创建/生成两个实例对象:
浏览器访问 “localhost:8080/log”
控制台输出:
符合预期!