一.spring的bean 属性scope作用域
scope属性
singleton:单例, 默认值,调⽤getBean⽅法返回是同⼀个对象,实例会被缓存起来,效率⽐ 较⾼
当⼀个bean被标识为singleton时候,spring的IOC容器中只会存在⼀个该bean
prototype: 多例,调⽤getBean⽅法创建不同的对象,会频繁的创建和销毁对象造成很⼤的
开销
其他少⽤ (作⽤域 只在 WebApplicationContext)
request :每个Http请求都会创建⼀个新的bean
session: 每个Http Session请求都会创建⼀个新的bean
global session(基本不⽤)
二.bean的注入
目录:
Video:
package net.xdclass.sp.domain;
import org.springframework.stereotype.Component;
public class Video {
private int id;
private String title;
public Video(){
}
public Video(String title){
System.out.println("video 带参数构造函数被调用");
this.title = title;
}
public int getId() {
return id;
}
public void setId(int id) {
System.out.println("Video setId方法被调用");
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
System.out.println("Video setTitle方法被调用");
this.title = title;
}
}
VideoOrder:
package net.xdclass.sp.domain;
import org.springframework.beans.factory.annotation.Autowired;
public class VideoOrder {
private int id;
//订单号
private String outTradeNo;
private Video video;
public VideoOrder(){
System.out.println("VideoOrder空构造函数被调用");
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getOutTradeNo() {
return outTradeNo;
}
public void setOutTradeNo(String outTradeNo) {
this.outTradeNo = outTradeNo;
}
public Video getVideo() {
return video;
}
public void setVideo(Video video) {
System.out.println("videoOrder setVideo方法被调用");
this.video = video;
}
}
实例代码实现:
一.当bean和启动类代码是如下图时:
运行结果截图:
结果分析:
因为bean对象中的property中有id和title两个属性,注入时是使用了set方法,也就是调用如下图两个方法(在video代码中有),最后getTitle获得title属性的value值
二.当bean和启动类代码是如下图时:
运行截图:
结果分析:
代码一的实现是用了set方法注入,而这里是含参构造注入,见下图构造函数(在video代码中)
重点:这里写了有参构造函数,那么上面一定要加一个无参构造,不然系统会把无参给取消掉,那么再执行set注入bean时会大量报错,所以一定别忘记加无参构造
三.当bean和启动类是如下图:
运行截图:
结果分析:
区别便在于执行了videoorder这个bean对象,用到的set注入,其中ref用了DI依赖,videoOrder其中包含了video对象
三.spring的常见的注入方式-List-Map
复杂类型注入,添加两个属性
<bean id="video" class="net.xdclass.sp.domain.Video" >
<!--list类型注⼊-->
<property name="chapterList">
<list>
<value>第⼀章SpringBoot</value>
<value>第⼆章Mybatis</value>
<value>第三章Spring</value>
</list>
</property>
<property name="videoMap">
<map>
<entry key="1" value="SpringCloud课程"></entry>
<entry key="2" value="⾯试课程"></entry>
<entry key="3" value="javaweb课程"></entry>
</map>
</property>
</bean>
public class Video {
private int id;
private String title;
private List<String> chapterList;
private Map<Integer,String> videoMap;
//省略set get⽅法
}
四.spring里面bean的依赖和继承
bean继承:两个类之间⼤多数的属性都相同,避免重复配置,通过bean标签的parent属性重⽤已
有的Bean元素的配置信息 继承指的是配置信息的复⽤,和Java类的继承没有关系
<bean id="video" class="net.xdclass.sp.domain.Video" scope="singleton">
<property name="id" value="9"/>
<property name="title" value="Spring 5.X课程" />
</bean>
<bean id="video2" class="net.xdclass.sp.domain.Video2" scope="singleton"
parent="video">
<property name="summary" value="这个是summary"></property>
</bean>
属性依赖: 如果类A是作为类B的属性, 想要类A⽐类B先实例化,设置两个Bean的依赖关系
<bean id="video" class="net.xdclass.sp.domain.Video" scope="singleton">
<property name="id" value="9"/>
<property name="title" value="Spring 5.X课程" />
</bean>
<!--设置两个bean的关系,video要先于videoOrder实例化-->
<bean id="videoOrder" class="net.xdclass.sp.domain.VideoOrder" dependson="video">
<property name="id" value="8" />
<property name="outTradeNo" value="23432fnfwedwefqwef2"/>
<property name="video" ref="video"/>
</bean>