案例1:
如果有一个Bean对象,对象注入给两个类,其中一个类(A)不对其进行修改,一个类(B)修改了Bean对象中的数据,在使用的时候,就会导致A拿到的是修改以后的数据,拿不到修改前的数据。
但是正常来说应该是B修改了以后 也只是修改自己,不应该影响A的使用。
Bean对象👇
package com.demo.component;
import com.demo.model.User;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
@Controller
public class UserBeans {
//Bean作用域设置
//1.枚举设置
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
//2.全局设置
//@Scope("prototype")
//扫描根 扫描路径 注册Bean对象
@Bean
public User user() {
User user = new User();
user.setId(1);
user.setName("zyz");
user.setPassword("123456");
return user;
}
}
A类👇
package com.demo.controller;
import com.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
/**
* author:zyz
*/
@Controller
public class User1Controller {
@Autowired
private User user;
public void getUser() {
//属性注入 获取到bean 就是之前UserBeans设置的zyz
System.out.println("user: "+user);
}
}
B类👇
package com.demo.controller;
import com.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
/**
* author:wxy
*/
@Controller
public class UserController {
//属性注入 获取Bean对象
@Autowired
private User user1;
public void getUser() {
System.out.println("user:"+user1);//zyz
//修改一下拿到的user
User u = user1;
u.setName("wxy");
System.out.println("u:"+u);//wxy
}
}
执行结果👇
这是因为Bean默认的模式是单例模式(singleton),也就是在使用同一个对象,使用Bean的时候,因为Bean对象已经存在,所以并不会创建一个新的Bean对象来使用,所以本质还是在使用那个对象。
使用单例模式(singleton)可以提高性能,Spring中的Bean作用域也就是单例模式,是默认的。
如果我们希望不使用单例模式,我们就可以设置Spring的Bean作用域。
Bean作用域及作用域设置
1.作用域定义
程序中变量的可用范围就叫做作用域。
单例作用域指的是在Spring中只有这一份Bean,修改后,读取的时候就是修改后的数据,并不会创建新的Bean,读取到原始值。
2.作用域分类(6种)
1.singleton——单例作用域(Spirng中Bean的默认作用域)
2.prototype——多例作用域
3.request——请求作用域
4.session——回话作用域
5.application——全局作用域
6.websocket——WebSocket作用域
前两种在Spring中,后面4种是在Spring MVC的
3.设置作用域
使用@Scope来设置
如果要设置为多例作用域👇
其中@Scope(“prototype”)是全局设置
@Scope(ConfigurableBeanFactory.SCOPE.PROTOTYPE)是枚举设置
package com.demo.component;
import com.demo.model.User;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
@Controller
public class UserBeans {
//Bean作用域设置
//1.枚举设置
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
//2.全局设置
//@Scope("prototype")
//扫描根 扫描路径 注册Bean对象
@Bean
public User user() {
User user = new User();
user.setId(1);
user.setName("zyz");
user.setPassword("123456");
return user;
}
}