一、Spring简介
优点:
简化开发
框架整合
发展史
1. Spring Framework系统架构图
2. 目前问题
- 代码书写现状
- 耦合度偏高
- 解决方案
- 使用对象时,在程序中不要主动使用new产生对象,转换为由外部提供对象
3. 核心概念
-
IOC(Inversion of Control)控制反转 控制权的反转 创建对象的控制权由程序员变为了spring
使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转。通俗的讲就是“将new对象的权利交给Spring,我们从Spring中获取对象使用即可” spring提前把new好的对象存放在一个容器中,这个容器就是核心容器
-
Spring技术对IoC思想进行了实现
-
Spring提供了一个容器,称为IOC容器,用来充当IoC思想中的“外部”
-
IOC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean
-
DI(Dependency Injection)依赖注入
-
类要依赖他的属性,所以我们说类的依赖就是他的属性
-
spring在创建对象时给对象的属性赋值 就称为依赖注入
-
spring ioc 容负责创建对象 我们称之为控制反转 创建对象的同时给属性赋值 我们称之为依赖注入
-
在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入。
我们从spring ioc容器中要了一个数据访问访问层对象赋给了 bookDao这个变量 ,这个过程就叫依赖注入
-
-
- 目标:充分解耦
- 使用IoC容器管理bean(IOC)
- 在IoC容器内将有依赖关系的bean进行关系绑定(DI)
- 最终效果
- 使用对象时不仅可以直接从IoC容器中获取,并且获取到的bean已经绑定了所有的依赖关系
二、Spring使用
1. IOC实现步骤
【第一步】导入Spring坐标
【第二步】定义Spring管理的类(接口与实现类)
【第三步】创建Spring配置文件,配置对应类作为Spring管理的bean对象
【第四步】初始化IOC容器(Spring核心容器/Spring容器),通过容器获取bean对象
【第一步】导入Spring坐标
<dependencies>
<!--spring核心依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.12</version>
</dependency>
<!--junit的依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
【第二步】定义Spring管理的类(接口)
BookDao接口和BookDaoImpl实现类
package com.tyhxzy.dao;
/**
* 书籍的DAO接口
*/
public interface BookDao {
/**
添加书籍
*/
void save();
}
package com.tyhxzy.dao.impl;
import com.tyhxzy.dao.BookDao;
/**
* 书籍DAO的实现类
*/
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("DAO:添加书籍到数据库");
}
}
BookService接口和BookServiceImpl实现类
package com.tyhxzy.service;
public interface BookService {
/**
添加书籍
*/
void save();
}
package com.tyhxzy.service.impl;
import com.tyhxzy.dao.BookDao;
import com.tyhxzy.dao.impl.BookDaoImpl;
import com.tyhxzy.service.BookService;
public class BookServiceImpl implements BookService {
//创建成员对象
private BookDao bookDao = new BookDaoImpl();
//实现业务方法
@Override
public void save() {
System.out.println("业务层:调用添加书籍的方法");
bookDao.save();
}
}
【第三步】创建Spring配置文件,配置对应类作为Spring管理的bean对象
- 定义applicationContext.xml配置文件并配置BookServiceImpl
- 注:如果顶部出现提示信息,选择Disable inspection
<?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">
<!--
bean标签:
bean标签的作用: 创建制定类的对象并且存储到spring的容器中
class: 指定你创建的对象所属的类的类全名
id: 该对象在容器中的唯一标识
-->
<bean id="bookService" class="com.tyhxzy.service.impl.BookServiceImpl"/>
</beans>
注意事项:bean定义时id属性在同一个上下文中(IOC容器中)不能重复
【第四步】初始化IOC容器(Spring核心容器/Spring容器),通过容器获取Bean对象
package com.tyhxzy.test;
import com.tyhxzy.service.BookService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppTest {
//测试:从spring的容器中获取对象
@Test
public void testGetBean(){
// //1.创建spring的容器,读取配置文件 , ApplicationContext 是spring的容器的根接口。
//ClassPathXmlApplicationContext这个容器特点:根据类路径去读取配置文件的。
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2. 通过id从spring的容器中查找对象
//BookService bookService = (BookService) context.getBean("bookService");
//从容器中获取对象的时候,告诉容器对象的类型即可
BookService bookService = context.getBean("bookService", BookService.class);
bookService.save();
//3。关闭容器(以后不需要关闭的)
context.close();
}
}
运行结果
2. DI实现步骤
【第一步】删除使用new的形式创建对象的代码
【第二步】提供依赖对象对应的setter方法
【第三步】配置service与dao之间的关系
实现代码
【第一步】删除使用new的形式创建对象的代码
package com.tyhxzy.service.impl;
import com.tyhxzy.dao.BookDao;
import com.tyhxzy.service.BookService;
public class BookServiceImpl implements BookService {
//【第一步】删除使用new的形式创建对象的代码,解除对象之间的耦合度
private BookDao bookDao;
//实现业务方法
@Override
public void save() {
System.out.println("业务层:调用添加书籍的方法");
bookDao.save();
}
}
【第二步】提供依赖对象对应的setter方法
package com.tyhxzy.service.impl;
import com.tyhxzy.dao.BookDao;
import com.tyhxzy.dao.impl.BookDaoImpl;
import com.tyhxzy.service.BookService;
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;
}
}
【第三步】配置service与dao之间的关系
在applicationContext.xml中配置
<?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">
<!--1. 创建Dao的对象,并且把该对象存储到了spring的容器中-->
<bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl"/>
<!--使用bean标签即可使用spring的ioc的功能,让spring创建BookServiceImpl这个类的对象
id: 该对象在容器中唯一标示,名字可以随意,但是要确保唯一性。
class: 通知spring帮我们创建制定类的对象,并且放入spring的容器中。
-->
<bean id="bookService" class="com.tyhxzy.service.impl.BookServiceImpl">
<!--给对象的bookDao的属性赋值
name: 属性名,属性名是依赖setter方法的。
ref: 引用,引用另外一个对象给该属性赋值。
-->
<property name="bookDao" ref="bookDao"/>
</bean>
</beans>
图解演示
<property name="" ref="引入对象的id值">
标签- name:属性名,属性名依赖setter方法
- ref: 引入的对象的id
3. Bean的基础配置
配置说明
Bean别名配置
<?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">
<!--1. 创建Dao的对象,并且把该对象存储到了spring的容器中-->
<bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl"/>
<!--name作用:给对象起一个别名,name与id的区别:id只能配置一个,name可以配置多个,name多个别名是使用,; 空格分隔-->
<bean id="bookService" name="bookService1,bookService2,bookService4 bookService5" class="com.tyhxzy.service.impl.BookServiceImpl">
<!--给对象的bookDao的属性赋值
name: 属性名,属性名是依赖setter方法的。
ref: 引用,引用另外一个对象给该属性赋值。
-->
<property name="bookDao" ref="bookDao"/>
</bean>
</beans>
package com.tyhxzy.test;
import com.tyhxzy.service.BookService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppTest {
//测试:从spring的容器中获取对象
@Test
public void testGetBean(){
// //1.创建spring的容器,读取配置文件 , ApplicationContext 是spring的容器的根接口。
//ClassPathXmlApplicationContext这个容器特点:根据类路径去读取配置文件的。
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2. 通过id从spring的容器中查找对象
//BookService bookService = (BookService) context.getBean("bookService");
//从容器中获取对象的时候,告诉容器对象的类型即可
BookService bookService = context.getBean("bookService2", BookService.class);
bookService.save();
//3。关闭容器(以后不需要关闭的)
context.close();
}
}
4. Bean作用范围配置
扩展:scope的取值不仅仅只有singleton和prototype,还有request、session、application、 websocket ,表示创建出的对象放置在web容器(tomcat)对应的位置。比如:request表示保存到request域中。
applicationContext.xml
<?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">
<!--1. 创建Dao的对象,并且把该对象存储到了spring的容器中-->
<bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl"/>
<!--name作用:给对象起一个别名,name与id的区别:id只能配置一个,name可以配置多个,name多个别名是使用,; 空格分隔
scope作用: 指定对象的作用范围, 常用两种: singleton(单例,默认) , prototype(多例)
-->
<bean id="bookService" name="bookService1,bookService2,bookService4 bookService5"
class="com.tyhxzy.service.impl.BookServiceImpl" scope="prototype">
<!--给对象的bookDao的属性赋值
name: 属性名,属性名是依赖setter方法的。
ref: 引用,引用另外一个对象给该属性赋值。
-->
<property name="bookDao" ref="bookDao"/>
</bean>
</beans>
package com.tyhxzy.test;
import com.tyhxzy.service.BookService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppTest {
//测试:从spring的容器中获取对象
@Test
public void testGetBean(){
// //1.创建spring的容器,读取配置文件 , ApplicationContext 是spring的容器的根接口。
//ClassPathXmlApplicationContext这个容器特点:根据类路径去读取配置文件的。
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2. 通过id从spring的容器中查找对象
//BookService bookService = (BookService) context.getBean("bookService");
//从容器中获取对象的时候,告诉容器对象的类型即可
BookService bookService1 = context.getBean("bookService2", BookService.class);
BookService bookService2 = context.getBean("bookService2", BookService.class);
System.out.println("两个对象是同一个吗?"+(bookService1==bookService2));
//3。关闭容器(以后不需要关闭的)
context.close();
}
}
最后给大家说明一下:在我们的实际开发当中,绝大部分的Bean是单例的,也就是说绝大部分Bean不需要配置scope属性。
- 在<bean>标签上如何配置别名?
- name属性可以配置
- 那Bean的默认作用范围是什么?如何修改?
- 单例,singleton.
- scope="prototype|singleton"
四、Bean的实例化
Bean的实例化方式有几种
bean本质上就是对象,创建bean使用构造方法完成
1. 实例化Bean的三种方式
1.1 构造方法方式
package com.tyhxzy.dao.impl;
import com.tyhxzy.dao.BookDao;
public class BookDaoImpl implements BookDao {
public BookDaoImpl() {
System.out.println("BookDaoImpl的无参构造方法创建了....");
}
@Override
public void save() {
System.out.println("DAO:添加了图书..");
}
}
applicationContext.xml配置
<?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">
<!--方式一: 利用一个类的无参构造方法创建 以后最为常用的一种方式
<bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl"/>
-->
</beans>
AppTest测试类
package com.tyhxzy.test;
import com.tyhxzy.dao.BookDao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppTest {
//测试:从spring的容器中获取对象
@Test
public void testGetBean(){
// //1.创建spring的容器,读取配置文件 , ApplicationContext 是spring的容器的根接口。
//ClassPathXmlApplicationContext这个容器特点:根据类路径去读取配置文件的。
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2. 通过id从spring的容器中查找对象
//BookService bookService = (BookService) context.getBean("bookService");
//从容器中获取对象的时候,告诉容器对象的类型即可
BookDao bookDao = context.getBean("bookDao", BookDao.class);
bookDao.save();
//3。关闭容器(以后不需要关闭的)
context.close();
}
}
注意:无参构造方法如果不存在,将抛出异常 BeanCreationException
1.2 静态工厂方式
BookFactoryBean工厂类
package com.tyhxzy.factory;
import com.tyhxzy.dao.BookDao;
import com.tyhxzy.dao.impl.BookDaoImpl;
public class BookFactoryBean {
/*
静态的工厂方法
*/
public static BookDao getBookDao(){
System.out.println("静态工厂方法...");
return new BookDaoImpl();
}
}
applicationContext.xml配置
<?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">
<!--方式一: 利用一个类的无参构造方法创建 以后最为常用的一种方式
<bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl"/>
-->
<!--方式二: 利用静态工厂方法创建对象
id: 该对象在spring容器中id
class: 静态工厂类的全类名
factory-method: 静态工厂的方法名
-->
<bean id="bookDao" class="com.tyhxzy.factory.BookFactoryBean" factory-method="getBookDao"/>
</beans>
applicationContext.xml配置
<?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">
<!--方式一: 利用一个类的无参构造方法创建 以后最为常用的一种方式
<bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl"/>
-->
<!--方式二: 利用静态工厂方法创建对象
id: 该对象在spring容器中id
class: 静态工厂类的全类名
factory-method: 静态工厂的方法名
-->
<bean id="bookDao" class="com.tyhxzy.factory.BookFactoryBean" factory-method="getBookDao"/>
</beans>
AppTest测试类
package com.tyhxzy.test;
import com.tyhxzy.dao.BookDao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppTest {
//测试:从spring的容器中获取对象
@Test
public void testGetBean(){
// //1.创建spring的容器,读取配置文件 , ApplicationContext 是spring的容器的根接口。
//ClassPathXmlApplicationContext这个容器特点:根据类路径去读取配置文件的。
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2. 通过id从spring的容器中查找对象
//BookService bookService = (BookService) context.getBean("bookService");
//从容器中获取对象的时候,告诉容器对象的类型即可
BookDao bookDao = context.getBean("bookDao", BookDao.class);
bookDao.save();
//3。关闭容器(以后不需要关闭的)
context.close();
}
}
运行结果
1.3 实例工厂方法方式
BookFactoryBean工厂类
package com.tyhxzy.factory;
import com.tyhxzy.dao.BookDao;
import com.tyhxzy.dao.impl.BookDaoImpl;
public class BookFactoryBean {
/*
非静态方法创建BookDaoImpl对象
*/
public BookDao getBookDao2(){
System.out.println("非静态工厂方法...");
return new BookDaoImpl();
}
}
applicationContext.xml配置
<?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">
<!--方式一: 利用一个类的无参构造方法创建 以后最为常用的一种方式
<bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl"/>
-->
<!--方式二: 利用静态工厂方法创建对象
id: 该对象在spring容器中id
class: 静态工厂类的全类名
factory-method: 静态工厂的方法名
<bean id="bookDao" class="com.tyhxzy.factory.BookFactoryBean" factory-method="getBookDao"/>
-->
<!--方式三:非静态工厂方法创建对象
步骤:
1. 创建工厂类的对象
2. 调用非静态方法创建制定类的对象
-->
<!--1. 创建工厂类的对象-->
<bean id="bookFactoryBean" class="com.tyhxzy.factory.BookFactoryBean"/>
<!--2. 调用非静态方法创建制定类的对象-->
<bean id="bookDao" factory-bean="bookFactoryBean" factory-method="getBookDao2"/>
</beans>
Bean的实例化方式有几种?
- 无参的构造器
- 工厂静态方法
- 工厂非静态方法
五、Bean的生命周期
1. 生命周期相关概念介绍
- 生命周期:从创建到消亡的完整过程
- bean生命周期:bean从创建到销毁的整体过程
- bean生命周期控制:在bean创建后到销毁前做一些事情
2.代码演示
提供生命周期控制方法
package com.tyhxzy.dao.impl;
import com.tyhxzy.dao.BookDao;
public class BookDaoImpl implements BookDao {
/*
如果BookDao对象创建的会调用init方法
*/
public void init(){
System.out.println("init方法被调用了,该类的对象已经被创建了..");
}
/*
销毁该类的对象前调用方法
*/
public void destroy(){
System.out.println("destroy被调用了,马上就要销毁该类对象了...");
}
@Override
public void save() {
System.out.println("DAO:添加了图书..");
}
}
applicationContext.xml配置
<?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">
<!--
init-method: 指定创建对象的时候调用的初始化方法的方法名
destroy-method: 销毁对象前指定调用的方法
默认情况spring使用的是饿汉单例设计模式,如果需要修改饿汉单例设计模式,可以lazy-init修改
lazy-init="true" 懒汉模式
lazy-init=false 饿汉模式 , 默认
-->
<bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl" init-method="init" lazy-init="true" destroy-method="destroy" />
</beans>
测试类
package com.tyhxzy.test;
import com.tyhxzy.dao.BookDao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/*
核心知识点:
1. 默认情况spring使用的是饿汉单例设计模式,不是懒汉单例设计模式。在容器启动就创建该类的对象了。
2. 容器关闭的时候才会销毁对象。
*/
public class AppTest {
//测试:从spring的容器中获取对象
@Test
public void testGetBean(){
// //1.创建spring的容器,读取配置文件 , ApplicationContext 是spring的容器的根接口。
//ClassPathXmlApplicationContext这个容器特点:根据类路径去读取配置文件的。
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
context.close();
//2. 通过id从spring的容器中查找对象
//BookService bookService = (BookService) context.getBean("bookService");
//从容器中获取对象的时候,告诉容器对象的类型即可
BookDao bookDao = context.getBean("bookDao", BookDao.class);
bookDao.save();
//3。关闭容器(以后不需要关闭的)
context.close();
// context.registerShutdownHook(); //这种方式是注册到jvm,通知jvm容器关闭的时候调用destroy方法。
}
}
spring的bean对象的生命周期? 与什么周期相关的两个属性?
-
创建spring容器的时候创建。
- init-method , destory-method
六、依赖注入(DI配置)
1. 依赖注入
1.1 依赖注入的两种方式
- setter注入
简单类型(八种基础数据类型+stirng类型)
引用类型(很常用) - 构造器注入
简单类型
引用类型
1.2 setter方式注入
问题导入
setter方式注入使用什么子标签?
引用类型
在bookService中使用ref注入bookDao
<?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">
<bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl"/>
<!--依赖注入方式一: 利用setter方法,使用property标签注入-->
<bean id="bookService" class="com.tyhxzy.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>
</beans>
简单类型
- 在BookDaoImpl中添加int connectionNumber
- 添加set方法
- 在配置文件中注入10
package com.tyhxzy.dao.impl;
import com.tyhxzy.dao.BookDao;
public class BookDaoImpl implements BookDao {
private int connectionNumber;
public void setConnectionNumber(int connectionNumber) {
this.connectionNumber = connectionNumber;
}
@Override
public void save() {
System.out.println("DAO:添加了图书.."+connectionNumber);
}
}
applicationContext.xml 文件
<?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">
<bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl">
<property name="connectionNumber" value="100"/>
</bean>
<!--依赖注入方式一: 利用setter方法,使用property标签注入-->
<bean id="bookService" class="com.tyhxzy.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>
</beans>
测试类
package com.tyhxzy.test;
import com.tyhxzy.dao.BookDao;
import com.tyhxzy.service.BookService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppTest {
//测试:从spring的容器中获取对象
@Test
public void testGetBean(){
//1. 获取容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2. 从容器中获取bookDao对象
BookDao bookDao = context.getBean("bookDao", BookDao.class);
bookDao.save();
//3 关闭容器
context.close();
}
}
1.3 构造方式注入
问题导入
构造方式注入使用什么子标签?
引用类型
- 给BookServiceImpl添加构造方法,参数是BookDao
- 在配置文件中给bookService中使用构造器注入bookDao
BookServiceImpl, 添加构造方法
package com.tyhxzy.service.impl;
import com.tyhxzy.dao.BookDao;
import com.tyhxzy.dao.impl.BookDaoImpl;
import com.tyhxzy.service.BookService;
public class BookServiceImpl implements BookService {
//service需要依赖Dao
private BookDao bookDao ;
//一个带参的构造方法
public BookServiceImpl(BookDao bookDao) {
this.bookDao = bookDao;
}
@Override
public void save() {
bookDao.save();
System.out.println("service:添加书本..");
}
//删除setter方法
// public void setBookDao(BookDao bookDao) {
// this.bookDao = bookDao;
// }
}
applicationContext.xml
<?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">
<bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl">
<property name="connectionNumber" value="100"/>
</bean>
<!--依赖注入方式一: 利用setter方法,使用property标签注入
<bean id="bookService" class="com.tyhxzy.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>
-->
<!--依赖注入方式二:利用构造方法给对象注入成员变量值-->
<bean id="bookService" class="com.tyhxzy.service.impl.BookServiceImpl">
<!--
index: 构造方法的参数的索引值,从0开始
name: 构造方法的形参的名字
<constructor-arg index="0" ref="bookDao"/>
-->
<constructor-arg name="bookDao" ref="bookDao"/>
</bean>
</beans>
测试类
package com.tyhxzy.test;
import com.tyhxzy.dao.BookDao;
import com.tyhxzy.service.BookService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppTest {
@Test
public void testGetServiceBean(){
//1. 获取容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2. 从容器中获取bookDao对象
BookService bookService = context.getBean("bookService", BookService.class);
bookService.save();
//3 关闭容器
context.close();
}
}
简单类型
-
给BookDao添加整数类型的构造方法
package com.tyhxzy.dao.impl; import com.tyhxzy.dao.BookDao;
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);
}
}
1. 使用配置通过构造器给BookDao注入属性值
```xml
<!--利用构造器方式初始化成员变量-->
<bean id="bookDao" class="com.tyhxzy.dao.impl.BookDaoImpl">
<constructor-arg name="connectionNumber" value="10"/>
<constructor-arg name="databaseName" value="spring_db"/>
</bean>
参数适配【了解】
- 按类型的方式匹配
- 按位置的方式匹配
步骤
-
添加新的成员变量:String databaseName
-
创建2个参数的构造方法
-
生成toString方法
package com.tyhxzy.dao.impl; import com.tyhxzy.dao.BookDao; /** * 书籍DAO的实现类 */ public class BookDaoImpl implements BookDao { //成员变量 private int connectionNumber; private String databaseName; //无参的构造方法 public BookDaoImpl() { } //1个参数的构造方法 public BookDaoImpl(int connectionNumber) { this.connectionNumber = connectionNumber; } //2个参数的构造方法 public BookDaoImpl(int connectionNumber, String databaseName) { this.connectionNumber = connectionNumber; this.databaseName = databaseName; } @Override public String toString() { return "BookDaoImpl{" + "connectionNumber=" + connectionNumber + ", databaseName='" + databaseName + '\'' + '}'; } }
-
分别使用类型匹配和位置匹配的方式注入值
2. 依赖自动装配【理解】
问题导入
如何配置按照类型自动装配?
2.1 自动装配概念
- IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配
- 自动装配方式
- 按名称
- 按构造方法
- 不启用自动装配
2.2 自动装配类型
applicationContext.xml
<?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">
<!--利用构造器方式初始化成员变量-->
<bean id="bookDao" class="com.tyhxzy.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.tyhxzy.service.impl.BookServiceImpl" autowire="byType"/>
</beans>
package com.tyhxzy.service.impl;
import com.tyhxzy.dao.BookDao;
import com.tyhxzy.dao.impl.BookDaoImpl;
import com.tyhxzy.service.BookService;
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:添加书本..");
}
}
测试类
package com.tyhxzy.test;
import com.tyhxzy.dao.BookDao;
import com.tyhxzy.service.BookService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppTest {
@Test
public void testGetServiceBean(){
//1. 获取容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2. 从容器中获取bookDao对象
BookService bookService = context.getBean("bookService", BookService.class);
bookService.save();
//3 关闭容器
context.close();
}
}
小结
依赖注入有几种方式,分别对应的是哪个标签或者属性
- 通过setter方法注入 property标签
- 构造方法注入 constructor-arg
3. 集合注入
3.1 注入数组类型数据
<property name="array">
<array>
<value>100</value>
<value>200</value>
<value>300</value>
</array>
</property>
3.2 注入List类型数据
<property name="list">
<list>
<value>itcast</value>
<value>tyhxzy</value>
<value>boxuegu</value>
<value>chuanzhihui</value>
</list>
</property>
3.3 注入Set类型数据
<property name="set">
<set>
<value>itcast</value>
<value>tyhxzy</value>
<value>boxuegu</value>
<value>boxuegu</value>
</set>
</property>
3.4 注入Map类型数据
<property name="map">
<map>
<entry key="country" value="china"/>
<entry key="province" value="henan"/>
<entry key="city" value="kaifeng"/>
</map>
</property>
3.5 注入Properties类型数据
<property name="properties">
<props>
<prop key="country">china</prop>
<prop key="province">henan</prop>
<prop key="city">kaifeng</prop>
</props>
</property>
说明:property标签表示setter方式注入,构造方式注入constructor-arg标签内部也可以写<array>、<list>、<set>、<map>、<props>标签
小结:
数组: array
list: list
set: set
map: map
properties: props
标签:容器,tyhxzy,Spring,context,import,com,public
From: https://www.cnblogs.com/YxinHaaa/p/17441661.html