1.默认情况下 spring 容器中都是单实例。
import io.mieux.bean.Person;
import io.mieux.BeanConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class App03 {
public static void main(String[] args) {
ApplicationContext applicationContext =
new AnnotationConfigApplicationContext(BeanConfig.class);
Person person1 = applicationContext.getBean(Person.class);
Person person2 = applicationContext.getBean(Person.class);
System.out.println(person1 == person2);
}
}
运行结果:
true
2.如果需要多实例,则需要使用 @Scope 注解,并将其 value 设为 ConfigurableBeanFactory.SCOPE_PROTOTYPE。
package io.mieux.config;
import io.mieux.bean.Person;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
public class BeanConfig {
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Person person() {
return new Person("zhangsan", 28);
}
}
运行效果:
false
3.singleton 和 prototype 的实例创建的时间是不一样的。singleton 在容器初始化的时候就被创建,而 prototype 则在需要获取实例的时候才被创建。可以通过在 BeanConfig 配置类创建 Person 实例时,增加一行输出来验证。
首先是 singleton 的验证,将 @Scope 的 value 修改为 ConfigurableBeanFactory.SCOPE_SINGLETON,并且暂时注释掉获取 person 实例部分的代码。
package io.mieux.config;
import io.mieux.bean.Person;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
public class BeanConfig {
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public Person person() {
System.out.println("创建 Person 实例");
return new Person("zhangsan", 28);
}
}
import io.mieux.BeanConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class App03 {
public static void main(String[] args) {
ApplicationContext applicationContext =
new AnnotationConfigApplicationContext(BeanConfig.class);
// Person person1 = applicationContext.getBean(Person.class);
// Person person2 = applicationContext.getBean(Person.class);
// System.out.println(person1 == person2);
}
}
运行效果:
创建 Person 实例
接着是 prototype 的验证,将 @Scope 的 value 修改为 ConfigurableBeanFactory.SCOPE_PROTOTYPE,先依然保持注释掉获取 person 实例部分的代码。
package io.mieux.config;
import io.mieux.bean.Person;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
public class BeanConfig {
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Person person() {
System.out.println("创建 Person 实例");
return new Person("zhangsan", 28);
}
}
运行之后并没有输出任何信息,说明了在容器初始化的时并没有创建实例。
将获取 person 实例部分的代码取消注释。
import io.mieux.config.BeanConfig;
import io.mieux.bean.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class App03 {
public static void main(String[] args) {
ApplicationContext applicationContext =
new AnnotationConfigApplicationContext(BeanConfig.class);
Person person1 = applicationContext.getBean(Person.class);
Person person2 = applicationContext.getBean(Person.class);
System.out.println(person1 == person2);
}
}
运行效果:
创建 Person 实例
创建 Person 实例
false
4.spring 默认使用的是 singleton,也就是刚才所说的,单实例,并且在容器初始化的时候就被创建。如果希望和 prototype 一样,在第一次使用实例时才创建,也就是常说的懒加载,就需要使用 @Lazy 注解。
在 BeanConfig 配置类的 person 方法上增加 @Lazy 注解。
package io.mieux.config;
import io.mieux.bean.Person;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.*;
@Configuration
public class BeanConfig {
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
@Lazy
public Person person() {
System.out.println("创建 Person 实例");
return new Person("zhangsan", 28);
}
}
先注释掉获取 person 实例部分的代码。
import io.mieux.config.BeanConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class App03 {
public static void main(String[] args) {
ApplicationContext applicationContext =
new AnnotationConfigApplicationContext(BeanConfig.class);
// Person person1 = applicationContext.getBean(Person.class);
// Person person2 = applicationContext.getBean(Person.class);
// System.out.println(person1 == person2);
}
}
运行之后并没有输出任何信息,说明了在容器初始化的时并没有创建实例。
接着取消掉获取 person1 实例的注释:
import io.mieux.config.BeanConfig;
import io.mieux.bean.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class App03 {
public static void main(String[] args) {
ApplicationContext applicationContext =
new AnnotationConfigApplicationContext(BeanConfig.class);
Person person1 = applicationContext.getBean(Person.class);
// Person person2 = applicationContext.getBean(Person.class);
// System.out.println(person1 == person2);
}
}
运行效果:
创建 Person 实例
运行结果就表明了,在第一次获取 person 实例时,才会创建 person 实例。
网友评论