一、@Scope注解详细信息如下:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Scope {
// scopeName和value属性互为别名,使用哪一个属性进行赋值,效果都是一样的
@AliasFor("scopeName")
String value() default "";
/**
* Specifies the name of the scope to use for the annotated component/bean.
* <p>Defaults to an empty string ({@code ""}) which implies
// 创建的是单实例对象
* {@link ConfigurableBeanFactory#SCOPE_SINGLETON SCOPE_SINGLETON}.
* @since 4.2
// 创建的是多实例对象
* @see ConfigurableBeanFactory#SCOPE_PROTOTYPE
* @see ConfigurableBeanFactory#SCOPE_SINGLETON
// 一次请求创建一个实例对象
* @see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST
// 一次会话创建一个实例对象
* @see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION
* @see #value
*/
@AliasFor("value")
String scopeName() default "";
ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;
}
二、@Scope注解的取值
1、可以从上面看出value的取值如下:
sigleton:创建单实例对象,每次获取的都是同一个对象
prototype:创建多实例对象,每次获取的都是不同的对象
request:一次请求创建一个实例对象
session:一次会话创建一个实例对象
2、测试@Scope("singleton")
配置类
@Configuration
@ComponentScan(value="com.spring01")
public class SpringConfiguration {
// Spring容器的默认值就是singleton
@Scope("singleton")
@Bean("xiaomao")
public Person person(){
System.out.println("创建Person对象");
return new Person("xiaomao",21);
}
}
测试类
public class SpringDemo {
@Test
public void springTest01() {
// 如果不设置@Scope或者@Scope("singleton")或者@Scope(value="singleton")或者@Scope(scopeName="singleton")
// 那么启动容器的时候便会创建对象,以后去获取就是从IOC容器中去取,并且每一次都拿的是同一个对象
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfiguration.class);
System.out.println("IOC容器创建完成");
Person bean1 = context.getBean("xiaomao", Person.class);
Person bean2 = context.getBean("xiaomao", Person.class);
System.out.println(bean1 == bean2);
}
}
测试结果
创建Person对象
IOC容器创建完成
true
结果分析:当@Scope("singleton")时,容器启动完成的时候便会创建对象,并注入到Spring容器中,交由Spring进行管理,每次获取对象的时候从IOC容器中直接获取,通过bean1==bean2可以看出,创建的对象是单实例的,它们就是同一个对象.
3、测试@Scope("prototype")
测试结果
IOC容器创建完成
创建Person对象
创建Person对象
false
结果分析:如果将@Scope的值设置为prototype,那么在IOC容器启动完成的时候不会去创建对象,只有在获取对象的时候才会去创建对象,并且每一次获取对象都是不同的对象
三、@Lazy
该注解的作用就是启用Spring的懒加载功能,当容器启动完成之后不会去创建对象,只有在真正的获取对象的时候才会创建该对象的实例
@Configuration
@ComponentScan(value="com.spring01")
public class SpringConfiguration {
// IOC容器创建完成时不会直接创建对象,只有在获取对象时才去创建对象
@Lazy
@Scope("singleton")
@Bean
public Person xiaomao(){
System.out.println("创建Person对象");
return new Person("xiaomao",21);
}
}