1、bean的作用域
1、新建一个maven工程,添加如下依赖
org.springframework
spring-context
5.0.5.RELEASE
2,新建一个实体Person类
packagecom.yefengyu.annotation.bean;public classPerson
{privateString name;privateInteger age;publicPerson()
{
}publicPerson(String name, Integer age)
{this.name =name;this.age =age;
}publicString getName()
{returnname;
}public voidsetName(String name)
{this.name =name;
}publicInteger getAge()
{returnage;
}public voidsetAge(Integer age)
{this.age =age;
}
@OverridepublicString toString()
{return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
3、新建一个配置类
packagecom.yefengyu.annotation.config;importcom.yefengyu.annotation.bean.Person;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;
@Configurationpublic classMainConfig
{
@BeanpublicPerson person()
{return new Person("张三", 20);
}
}
4、测试
public static voidmain(String[] args)
{
ApplicationContext ctx= new AnnotationConfigApplicationContext(MainConfig.class);
Person person1= (Person)ctx.getBean("person");
Person person2= (Person)ctx.getBean("person");
System.out.println(person1== person2); //true
}
上面结果看出从容器多次获取一个bean,其实都是同一个对象,这是由于bean的作用域是 单实例 造成的。
prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。每次获取的时候才会调用方法创建对象;
singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。以后每次获取就是直接从容器中拿,
request:同一次请求创建一个实例
session:同一个session创建一个实例
此外我们可以修改配置类,增加打印,方便观察:
@Configurationpublic classMainConfig
{
@BeanpublicPerson person()
{
System.out.println("创建Person对象");return new Person("张三", 20);
}
}
我们再次运行上面的测试代码发现 创建Person对象 这句只打印了一次。
5、使用方式:Scope注解
@Configurationpublic classMainConfig
{
@Bean
@Scope("prototype")publicPerson person()
{
System.out.println("创建Person对象");return new Person("张三", 20);
}
}
注意:Scope注解是对bean的作用域进行修饰,可以修改bean的作用域,可以和@Bean注解与@Component系列注解一起使用。
我们再次运行上面的测试代码发现 创建Person对象 这句打印了两次。并且两个对象不相同,使用 == 比较返回 false.
Scope中的值可以使用上面的字符串,例如prototype,也可以使用
ConfigurableBeanFactory.SCOPE_PROTOTYPE
ConfigurableBeanFactory.SCOPE_SINGLETON
WebApplicationContext.SCOPE_REQUEST
WebApplicationContext.SCOPE_SESSION
2、懒加载
专门针对单实类,也叫延迟加载。
@Configurationpublic classMainConfig
{
@BeanpublicPerson person()
{
System.out.println("创建Person对象");return new Person("张三", 20);
}
}
单实例bean:默认在容器启动的时候创建对象;
AnnotationConfigApplicationContext ctx =new AnnotationConfigApplicationContext(MainConf.class);
下面这段测试代码并没有使用到 person ,但是通过打印我们可以看出已经加载了Person对象。
public static voidmain(String[] args)
{
ApplicationContext ctx= new AnnotationConfigApplicationContext(MainConfig.class);
String[] names=ctx.getBeanDefinitionNames();for(String name : names)
{
System.out.println(name);
}
}
创建Person对象
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
person
现在我们加上一个注解@Lazy
@Configurationpublic classMainConfig
{
@Bean
@LazypublicPerson person()
{
System.out.println("创建Person对象");return new Person("张三", 20);
}
}
此时再次测试,得出的结果如下
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
person
说明在延迟加载的情况下,如果没有使用到bean,那么就不会在容器真正创建一个对象(没有打印 :创建Person对象 ),现在我们在测试代码加上对 person对象的获取。
public static voidmain(String[] args)
{
ApplicationContext ctx= new AnnotationConfigApplicationContext(MainConfig.class);
String[] names=ctx.getBeanDefinitionNames();for(String name : names)
{
System.out.println(name);
}
Person person= (Person)ctx.getBean("person");
}得到的结果如下,注意打印顺序
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
person
创建Person对象
懒加载归纳:容器启动不创建对象。第一次使用(获取)Bean时创建对象,并初始化