SpringBean的作用域
和正常创建对象一样,在 Spring 中用 bean 配置的对象也有对应的作用域,可以在 bean 标签中通过 scope 属性进行设置
- Singleton单例模式(默认)
<bean id="user" class="com.baifu.pojo.User" p:name="baifu" p:age="15" scope="singleton"/>
若一个 bean 的作用域设置为 singleton,则在程序运行过程中一个类只有一个对象,任何对该对象的引用都是在引用同一个对象(就是单例模式)。
官方文档的图解
用测试方法测试一下,之前也做过这个测试,即从 bean 中获取一个对象两次,看看它们是否相同
@Test
public void Test2(){
ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
// 反射!就知道是什么类了!
User user = context.getBean("user", User.class);
User user2 = context.getBean("user", User.class);
System.out.println(user.hashCode());
System.out.println(user2.hashCode());
System.out.println(user == user2);
}
//93503335
//93503335
//true
- Prototype 原型模式: 每次从容器中get的时候,都产生一个新对象!
<bean id="user" class="com.baifu.pojo.User" p:name="baifu" p:age="15" scope="prototype"/>
若一个 bean 被设置为了原型,则每个对该对象的引用都会创建一个新的该对象。简单来说,就是这个 bean 是一个模板,用到的时候就按照模板创建一个出来。
官方文档的图解
用测试方法测试一下,之前也做过这个测试,即从 bean 中获取一个对象两次,看看它们是否相同
@Test
public void Test2(){
ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
// 反射!就知道是什么类了!
User user = context.getBean("user", User.class);
User user2 = context.getBean("user", User.class);
System.out.println(user.hashCode());
System.out.println(user2.hashCode());
System.out.println(user == user2);
}
//93503335
//93503335
//false
注意:一般来说,写实体类的时候只会添加构造器、get/set 方法、toString 方法,不会重写 equals 方法和 hashCode 方法。但我的实体类使用了 Lombok,直接 @Data 重写了这个两个方法,导致这里 hashCode 相同但使用 == 比较却为 false。
hashCode 是所有 java 对象的固有方法,如果不重载的话,返回的实际上是该对象在 jvm 的堆上的内存地址,而不同对象的内存地址肯定不同,所以这个 hashCode 也就肯定不同了。如果重载了的话,由于采用的算法的问题,有可能导致两个不同对象的 hashCode 相同。
-
其余的request、session、application这些只能在web开放中使用!
-
request 与 web 中的 request 作用域相同,只在一次请求中有效( single HTTP request )
-
session 与 web 中的 session 作用域相同,在会话建立后直到关闭前有效( HTTP Session )
-
application 与 web 中的 ServletContext 作用域相同,在服务器开启后直到关闭前有效
-
参考: https://blog.youkuaiyun.com/qq_43560701/article/details/119880396