1.核心概念
IoC(Inversion of Control)控制反转
对象的创建控制权由程序转移到外部,这种思想称为控制反转
Spring技术对IoC思想进行了实现
Spring提供了一个容器,称为IoC容器,用来充当IoC思想中的“外部”
IoC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean
DI(Dependency Injection)依赖注入
在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入
首先导入依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.14</version>
</dependency>
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
然后创建对应的类,并导入bean标签
public class BookDaoImpl implements BookDao {
@Override
public void save() {
System.out.println("DAO:添加了图书..");
}
}
创建xml文件
applicationContext.xml
<bean id="bookService" class="com.mywork.service.impl.BookServiceImpl"/>
2.给bean对象赋值,注意赋值是依赖于set方法的,在实现类里必须要有set方法
public class BookServiceImpl implements BookService {
//service需要依赖Dao
private BookDao bookDao ;
@Override
public void save() {
bookDao.save();
System.out.println("service:添加书本..");
}
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
}
id:bean的id,使用容器可以通过id值获取对应的bean,在一个容器中id值唯一
class:bean的类型,即配置的bean的全路径类名
<!--1. 创建Dao的对象,并且把该对象存储到了spring的容器中-->
<bean id="bookDao" class="com.mywork.dao.impl.BookDaoImpl"/>
<!--使用bean标签即可使用spring的ioc的功能,让spring创建BookServiceImpl这个类的对象
id: 该对象在容器中唯一标示,名字可以随意,但是要确保唯一性。
class: 通知spring帮我们创建制定类的对象,并且放入spring的容器中。
-->
<bean id="bookService" class="com.mywork.service.impl.BookServiceImpl">
<!--给对象的bookDao的属性赋值
name: 属性名,属性名是依赖setter方法的。
ref: 引用,引用另外一个对象给该属性赋值。
-->
<property name="bookDao" ref="bookDao"/>
</bean>
3.name 和scope
scope用来指定是单例还是多例,所谓单例就是指所有请求都用一个对象来处理;多例就是指每个请求用一个新的对象来处理;
<!--name作用:给对象起一个别名,name与id的区别:id只能配置一个,name可以配置多个,name多个别名是使用,; 空格分隔
scope作用: 指定对象的作用范围, 常用两种: singleton(单例,默认) , prototype(多例)
-->
<bean id="bookService" name="bookService1,bookService2,bookService4 bookService5"
class="com.mywork.service.impl.BookServiceImpl" scope="prototype">
<!--给对象的bookDao的属性赋值
name: 属性名,属性名是依赖setter方法的。
ref: 引用,引用另外一个对象给该属性赋值。
-->
<property name="bookDao" ref="bookDao"/>
</bean>
4.不同方式创建实例
<!--方式一: 利用一个类的无参构造方法创建 以后最为常用的一种方式
<bean id="bookDao" class="com.mywork.dao.impl.BookDaoImpl"/>
-->
<!--方式二: 利用静态工厂方法创建对象
id: 该对象在spring容器中id
class: 静态工厂类的全类名
factory-method: 静态工厂的方法名
<bean id="bookDao" class="com.itheima.factory.BookFactoryBean" factory-method="getBookDao"/>
-->
<!--方式三:非静态工厂方法创建对象
步骤:
1. 创建工厂类的对象
2. 调用非静态方法创建制定类的对象
-->
<!--1. 创建工厂类的对象-->
<bean id="bookFactoryBean" class="com.itheima.factory.BookFactoryBean"/>
<!--2. 调用非静态方法创建制定类的对象-->
<bean id="bookDao" factory-bean="bookFactoryBean" factory-method="getBookDao2"/>
5.指定生命周期的调用方法
懒汉式一开始不会实例化,什么时候用就什么时候new,才进行实例化
饿汉式在一开始类加载的时候就已经实例化,并且创建单例对象,以后只管用即可。
<!--
init-method: 指定创建对象的时候调用的初始化方法的方法名
destroy-method: 销毁对象前指定调用的方法
默认情况spring使用的是饿汉单例设计模式,如果需要修改饿汉单例设计模式,可以lazy-init修改
lazy-init="true" 懒汉模式
lazy-init=false 饿汉模式 , 默认
-->
<bean id="bookDao" class="com.mywork.dao.impl.BookDaoImpl" init-method="init" lazy-init="true" destroy-method="destroy" />
6.依赖注入
可以看到有setter和构造注入两种方式
<!--利用构造器方式初始化成员变量-->
<bean id="bookDao" class="com.mywork.dao.impl.BookDaoImpl">
<constructor-arg name="connectionNumber" value="10"/>
<constructor-arg name="databaseName" value="spring_db"/>
</bean>
<!--依赖注入方式一: 利用setter方法,使用property标签注入
<bean id="bookService" class="com.mywork.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>
-->
<!--依赖注入方式二:利用构造方法给对象注入成员变量值-->
<bean id="bookService" class="com.mywork.service.impl.BookServiceImpl">
<!--
index: 构造方法的参数的索引值,从0开始
name: 构造方法的形参的名字
<constructor-arg index="0" ref="bookDao"/>
-->
<constructor-arg name="bookDao" ref="bookDao"/>
</bean>
public class BookDaoImpl implements BookDao {
private int connectionNumber;
private String databaseName;
/* public void setConnectionNumber(int connectionNumber) {
this.connectionNumber = connectionNumber;
}*/
public BookDaoImpl(int connectionNumber) {
this.connectionNumber = connectionNumber;
}
public BookDaoImpl(int connectionNumber, String databaseName) {
this.connectionNumber = connectionNumber;
this.databaseName = databaseName;
}
@Override
public void save() {
System.out.println("DAO:添加了图书.."+connectionNumber+" 数据库的名称:"+ databaseName);
}
}
7.依赖自动注入
<!--利用构造器方式初始化成员变量-->
<bean id="bookDao" class="com.mywork.dao.impl.BookDaoImpl">
<constructor-arg name="connectionNumber" value="10"/>
<constructor-arg name="databaseName" value="spring_db"/>
</bean>
<!--autowire: 创建该类对象的时候成员变量的初始化可以根据类型赋值,自动注入是依赖setter方法
创建BookServiceImpl对象的时候发现,该类有一个成员变量需要BookDao,那么spring就会自动从容器中去
查找是否有BookDao这种类型的对象。
-->
<bean id="bookService" class="com.mywork.service.impl.BookServiceImpl" autowire="byType"/>
public class BookServiceImpl implements BookService {
//service需要依赖Dao
private BookDao bookDao ;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
@Override
public void save() {
bookDao.save();
System.out.println("service:添加书本..");
}
}
public class BookDaoImpl implements BookDao {
private int connectionNumber;
private String databaseName;
/* public void setConnectionNumber(int connectionNumber) {
this.connectionNumber = connectionNumber;
}*/
public BookDaoImpl(int connectionNumber) {
this.connectionNumber = connectionNumber;
}
public BookDaoImpl(int connectionNumber, String databaseName) {
this.connectionNumber = connectionNumber;
this.databaseName = databaseName;
}
@Override
public void save() {
System.out.println("DAO:添加了图书.."+connectionNumber+" 数据库的名称:"+ databaseName);
}
}
8.集合属性赋值
<bean id="bookDao" class="com.mywork.dao.impl.BookDaoImpl">
<!--数组类型. 类型赋值就是使用array标签-->
<property name="arr">
<array>
<value>110</value>
<value>220</value>
<value>330</value>
</array>
</property>
<!--list集合赋值使用list标签-->
<property name="list">
<list>
<value>狗娃</value>
<value>狗剩</value>
<value>铁蛋</value>
</list>
</property>
<property name="set">
<set>
<value>凤姐</value>
<value>芙蓉</value>
<value>如花</value>
</set>
</property>
<property name="map">
<map>
<entry key="凤姐" value="阿强"/>
<entry key="芙蓉" value="阿伟"/>
<entry key="如花" value="阿东"/>
</map>
</property>
<property name="properties">
<props>
<prop key="username">root</prop>
<prop key="password">root</prop>
<prop key="url">jdbc:mysql:///spring-test</prop>
</props>
</property>
</bean>
public class BookDaoImpl implements BookDao {
private int[] arr; //数组
private List<String> list; //list
private Set<String> set; //set集合
private Map<String,String> map; //map集合
private Properties properties; 配置文件
public void setArr(int[] arr) {
this.arr = arr;
}
public void setList(List<String> list) {
this.list = list;
}
public void setSet(Set<String> set) {
this.set = set;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public void save() {
System.out.println("Dao的save方法");
}
@Override
public String toString() {
return "BookDaoImpl{" +
"arr=" + Arrays.toString(arr) +
", list=" + list +
", set=" + set +
", map=" + map +
", properties=" + properties +
'}';
}
}