spring单例模式
spring的默认bean注入为单例,以下通过简单的例子进行测试:
- 创建2个类,分别为singleton单例和prototype类型
@Component
@Scope(ConfigurableListableBeanFactory.SCOPE_SINGLETON)// 默认为单例,这里可以不写
public class SingletonUser {
private String name;
// 省略getter/setter方法...
}
protype类型的user
@Component
@Scope(ConfigurableListableBeanFactory.SCOPE_PROTOTYPE)
public class PrototypeUser {
private String name;
// 省略getter/setter方法...
}
- 通过不同service进行注入,改变其值
@Service
public class UserService1 {
@Autowired
private PrototypeUser prototypeUser;
@Autowired
private SingletonUser singletonUser;
public void testProto(){
prototypeUser.setName("李四");
System.out.println(prototypeUser.getName());
}
public void testSingleton(){
singletonUser.setName("X");
System.out.println(singletonUser.getName());
}
public PrototypeUser getPrototypeUser() {
return prototypeUser;
}
public SingletonUser getSingletonUser() {
return singletonUser;
}
}
userService2
@Service
public class UserService2 {
@Autowired
private PrototypeUser prototypeUser;
@Autowired
private SingletonUser singletonUser;
public void testProto(){
prototypeUser.setName("张三");
System.out.println(prototypeUser.getName());
}
public void testSingleton(){
singletonUser.setName("Y");
System.out.println(singletonUser.getName());
}
public PrototypeUser getPrototypeUser() {
return prototypeUser;
}
public SingletonUser getSingletonUser() {
return singletonUser;
}
}
- 编写测试类
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootThreadApplicationTests {
@Test
public void contextLoads() {
}
@Autowired
private UserService1 userService1;
@Autowired
private UserService2 userService2;
/**
* 测试单例
*/
@Test
public void testUser(){
userService1.testProto();
userService2.testProto();
userService1.testSingleton();
userService2.testSingleton();
/**
* 为false,说明是不同对象,多例
*/
System.out.println(userService1.getPrototypeUser().equals(userService2.getPrototypeUser()));
/**
* 为true,说明是同一个对象,单例
*/
System.out.println(userService1.getSingletonUser().equals(userService2.getSingletonUser()));
}
}
运行结果:
李四
张三
X
Y
false
true
结论:
- 可以对注入的对象进行赋值;
- spring默认采用的注入对象是单例的,即userService1和userService2两个实例得到的singletonUser是相同的,但是得到的prototypeUser 确实不同的。