Spring IoC
Spring IoC 容器组件,可以完成对象的创建、对象的属性赋值、对象管理
Spring框架部署(IoC)
新建Maven工程
- java
- web
添加Spring IoC依赖
- core
- beans
- aop
- expression
- context
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.13.RELEASE</version>
</dependency>
</dependencies>
创建Spring配置文件
通过配置文件”告诉“Spring容器创建什么对象,给对象属性赋值,赋什么值
-
在resources目录下创建名为applicationContext.xml的文件
-
创建Spring-ioc模板
-
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" > </beans>
SpringIoC使用
使用Spring IoC组件创建并管理对象
1、创建实体类
public class Student {
public String stuNum;
public String stuName;
public String stuSex;
public String stuAge;
public Date enterTime;
public String getStuNum() {
return stuNum;
}
public void setStuNum(String stuNum) {
this.stuNum = stuNum;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public String getStuSex() {
return stuSex;
}
public void setStuSex(String stuSex) {
this.stuSex = stuSex;
}
public String getStuAge() {
return stuAge;
}
public void setStuAge(String stuAge) {
this.stuAge = stuAge;
}
public Date getEnterTime() {
return enterTime;
}
public void setEnterTime(Date enterTime) {
this.enterTime = enterTime;
}
@Override
public String toString() {
return "Student{" +
"stuNum='" + stuNum + '\'' +
", stuName='" + stuName + '\'' +
", stuSex='" + stuSex + '\'' +
", stuAge='" + stuAge + '\'' +
", enterTime=" + enterTime +
'}';
}
}
2、在配置文件中配置文件地址
<bean id="stu" class="com.ccl.ioc.bean.Student">
<property name="stuNum" value="10001"/>
<property name="stuName" value="张三"/>
<property name="stuAge" value="19"/>
<property name="stuSex" value="男"/>
<property name="enterTime" value="2021-10-23"/>
</bean>
3、初始化Spring容器
ClassPathXmlApplicationContext
public class TestStudent {
public static void main(String[] args) {
//初始化Spring容器,加载Spring配置文件
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//通过Spring容器获取Student对象
Student student1 = (Student) context.getBean("stu");
System.out.println(student1);
}
}
IoC和DI
- IoC (Inverse of Control) 控制反转,依赖Spring对象工厂完成对象的创建(工厂设计模式)
- DI (Dependency Injection)依赖注入,在Spring完成对象创建的同时依赖Spring容器完成对象属性的赋值
IoC
当我们需要通过Spring对象工厂创建某个类的对象时,需要将这个交给Spring管理
bean id="stu" class="com.ccl.ioc.Student">
<property name="stuNum" value="1"/>
<property name="stuName" value="LiHua"/>
<property name="stuSex" value="man"/>
<property name="stuAge" value="18"/>
<property name="enterTime" ref="date"/>
</bean>
DI
通过Spring容器给创建的对象属性赋值
<bean id="stu" class="com.ccl.ioc.Student" autowire="byName">
<property name="stuNum" value="1"/>
<property name="stuName" value="LiHua"/>
<property name="stuSex" value="man"/>
<property name="stuAge" value="18"/>
<property name="enterTime" ref="date"/>
</bean>
<bean id="date" class="java.util.Date"/>
<bean id="clazz" class="com.ccl.ioc.Clazz"/>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XcjR8lIN-1635293279168)(C:\Users\13749\Desktop\csdn博客截图\微信截图_20211023201223.png)]
DI依赖注入
Spring容器加载配置文件之后,通过反射创建类的对象,并给属性赋值。Spring容器通过反射实现属性注入有三种方式:
- set方法
- 构造器注入
- 接口注入(不常用)
构造器注入
使用被Spring管理的类完成注入
- 简单类型、字符串、对象
public class Student {
public Integer stuNum;
public String stuName;
public String stuSex;
public Integer stuAge;
public Date enterTime;
public Clazz clazz;
public Student(Integer stuNum, String stuName, String stuSex, Integer stuAge, Date enterTime, Clazz clazz) {
this.stuNum = stuNum;
this.stuName = stuName;
this.stuSex = stuSex;
this.stuAge = stuAge;
this.enterTime = enterTime;
this.clazz = clazz;
}
}
-
集合类型
-
<bean id="list" class="com.ccl.ioc.Student"> <constructor-arg index="0"> <list> <value>11</value> <value>22</value> <value>33</value> </list> </constructor-arg> <constructor-arg index="1"> <set> <value>aa</value> <value>bb</value> <value>cc</value> </set> </constructor-arg> <constructor-arg index="2"> <map> <entry> <key><value>key1</value></key> <value>value1</value> </entry> <entry> <key><value>key2</value></key> <value>value2</value> </entry> </map> </constructor-arg> <constructor-arg> <props> <prop key="k1">k1</prop> <prop key="k2">k2</prop> </props> </constructor-arg></bean>
public List<String> hobbies;public Set<String> sets;public Map<String,Object> maps;public Properties properties;public Student(List<String> hobbies, Set<String> sets, Map<String, Object> maps, Properties properties) { this.hobbies = hobbies; this.sets = sets; this.maps = maps; this.properties = properties;}
注入
在bean标签中配置properties标签给属性赋值,实际上就是通过反射调用set方法完成属性注入
简单类型的属性、字符串赋值方法一样
-
直接通过property标签的value属性赋值
-
<bean id="stu" class="com.ccl.ioc.Student"> <property name="stuNum" value="10001"></property> <property name="stuAge" value="12"></property> <property name="weight" value="65.5"></property> <property name="enterTime" ref="date"></property></bean><bean id="date" class="java.util.Date"/>
-
日期赋值方法一:在property标签中通过引用Spring容器中的一个对象
<bean id="stu" class="com.ccl.ioc.Student"> <property name="enterTime" ref="date"></property></bean><bean id="date" class="java.util.Date"/>
-
方式二:在property标签中添加子标签来指定对象
-
<bean id="stu" class="com.ccl.ioc.Student"> <property name="stuNum" value="10001"></property> <property name="stuAge" value="12"></property> <property name="weight" value="65.5"></property> <property name="enterTime"> <bean class="java.util.Date"></bean> </property></bean>
自定义类对象属性
-
方式一:ref直接引用
<bean id="stu" class="com.ccl.ioc.Student"> <property name="clazz" ref="clazz"></property></bean><bean id="clazz" class="com.ccl.ioc.Clazz"> <property name="clazzId" value="1"/> <property name="clazzName" value="java2021"/></bean>
-
方式二:
-
<bean id="stu" class="com.ccl.ioc.Student"> <property name="clazz" > <bean id="clazz" class="com.ccl.ioc.Clazz"> <property name="clazzId" value="1"/> <property name="clazzName" value="java2021"/> </bean> </property></bean>
-
集合类型
-
list
-
set
-
map
Bean的作用域
在Bean标签可以通过scope属性指定对象的作用域
- scope=”singleton“表示当前是单例模式(饿汉模式,Spring加载时会创建对象;在bean标签中设置lazy-init="true"变为懒汉模式)
- 如果设置scope="prototype"表示当前bean非单例模式,每次通过Spring容器获取对象时都会创建一个新的对象
-
单例
-
<bean id="book" class="com.ccl.ioc.Book" scope="singleton" ></bean>
-
多例
-
<bean id="book" class="com.ccl.ioc.Book" scope="prototype"></bean>
Bean生命周期方法
public class Book { //初始化方法:创建当前对象调用的方法 public void init(){ System.out.println("创建当前对象调用的方法"); } //销毁方法:销毁对象时调用此方法,进行资源回收的方法 public void destory(){ System.out.println("销毁对象时调用此方法,进行资源回收的方法"); } public Book(){ System.out.println("构造器"); }}
<bean id="book" class="com.ccl.ioc.Book" scope="prototype" init-method="init"></bean>
自动装配
自动装配:Spring在实例化当前Bean的时候,从Spring容器中找到匹配的实例,赋值给当前匹配的属性
- 自动装配:
- byName
- byType
<bean id="clazz" class="com.ccl.ioc.Clazz"></bean><bean id="stu2" class="com.ccl.ioc.Student" autowire="byName"></bean>
byName 根据当前Bean的属性名在Spring容器中寻找匹配的对象,如果根据name找到了bean但是类型不匹配会抛出异常
<bean id="clazz2" class="com.ccl.ioc.Clazz"></bean><bean id="stu2" class="com.ccl.ioc.Student" autowire="byType"></bean>
byType 根据当前Bean的 属性类型在Spring容器中寻找匹配的对象,如果根据类型找到了多个类型匹配的Bean也会抛出异常