一、spring是什么?
Spring是一个轻量级的IOC和AOP容器框架
二、为什么要学习Spring?
1.spring属于低侵入式设计,代码污染极低
2.spring的DI机制将对象之间的依赖关系交由框架处理,减低组件的耦合性
3.spring提供了AOP技术,支持将一些通用任务如安全,事务,日志等进行集中式处理,提高复用
4.spring对于主流的应用框架提供了集成支持
三、Spring核心概念
目前代码出现的问题:
从上图可以看出代码的耦合性较高
解决方案:使用对象时不主动new对象,转为由外部提供
IOC控制反转
使用对象时,由主动new创建对象转为由外部提供,此过程中对象创建控制权由程序转到外部,此思想称为控制反转
Spring技术对IOC思想进行了实现
Spring提供一个IOC容器,用来充当IOC思想的外部
IOC容器负责对象的创建、初始化等一系列操作,被创建或被管理的对象在IOC容器中称之为Bean
DI依赖注入
在容器中建立Bean与Bean之间的依赖关系的这个过程,称为依赖注入
目标:充分解耦
最终效果:
使用对象时不仅可以直接从IOC容器中获取,并且获取到的Bean已经绑定了所有的依赖关系
IOC入门案例
1.1 门案例思路分析
-
管理什么?(Service与Dao)
-
如何将被管理的对象告知IOC容器?(配置文件)
-
被管理的对象交给IOC容器,如何获取到IoC容器?(接口)
-
IOC容器得到后,如何从容器中获取bean?(接口方法)
-
使用Spring导入哪些坐标?(pom.xml)
【第一步】导入Spring坐标
<dependencies>
<!--导入spring的坐标spring-context,对应版本是5.2.10.RELEASE-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
【第二步】定义Spring管理的类(接口)
BookDao接口和BookDaoImpl实现类
public interface BookDao {
public void save();
}
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
}
BookService接口和BookServiceImpl实现类
public interface BookService {
public void save();
}
public class BookServiceImpl implements BookService {
private BookDao bookDao = new BookDaoImpl();
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
【第三步】创建Spring配置文件,配置对应类作为Spring管理的bean对象
定义applicationContext.xml配置文件并配置BookServiceImpl
<?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
id属性:表示给bean起名字
class属性:表示给bean定义类型
-->
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"></bean>
</beans>
注意事项:bean定义时id属性在同一个上下文中(IOC容器中)不能重复
【第四步】初始化IOC容器(Spring核心容器/Spring容器),通过容器获取Bean对象
public class App {
public static void main(String[] args) {
//1.创建IoC容器对象,加载spring核心配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//2 从IOC容器中获取Bean对象(BookService对象)
BookService bookService= (BookService)ctx.getBean("bookService");
//3 调用Bean对象(BookService对象)的方法
bookService.save();
}
}
1.4 运行结果
DI入门案例
2.1 DI入门案例思路分析
-
基于IOC管理bean
-
Service中使用new形式创建的Dao对象是否保留?(否)
-
Service中需要的Dao对象如何进入到Service中?(提供方法)
-
Service与Dao间的关系如何描述?(配置)
【第一步】删除使用new的形式创建对象的代码
public class BookServiceImpl implements BookService {
private BookDao bookDao; //【第一步】删除使用new的形式创建对象的代码
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
【第二步】提供依赖对象对应的setter方法
public class BookServiceImpl implements BookService {
private BookDao bookDao;
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
//【第二步】提供依赖对象对应的setter方法
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
}
【第三步】配置service与dao之间的关系
<?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
id属性:表示给bean起名字
class属性:表示给bean定义类型
-->
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<!--配置server与dao的关系
property标签:表示配置当前bean的属性
name属性:表示配置哪一个具体的属性
ref属性:表示参照哪一个bean
-->
<property name="bookDao" ref="bookDao"/>
</bean>
</beans>
三、Bean的基础配置
1.Bean的基础配置
2.Bean别名配置
代码演示
3.Bean作用范围配置
扩展:scope的取值不仅仅只有singleton和prototype,还有request、session、application、 websocket ,表示创建出的对象放置在web容器(tomcat)对应的位置。比如:request表示保存到request域中。
代码演示
四、Bean的实例化
Bean是如何创建的?
Bean的本质上就是对象,通过构造方法完成创建
1.构造方法方式
BookDaoImpl实现类
public class BookDaoImpl implements BookDao {
public BookDaoImpl() {
System.out.println("book dao constructor is running ....");
}
public void save() {
System.out.println("book dao save ...");
}
}
applicationContext.xml配置
<!--方式一:构造方法实例化bean-->
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
AppForInstanceBook测试类
public class AppForInstanceBook {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
bookDao.save();
}
}
注意:无参构造方法如果不存在,将抛出异常BeanCreationException
2.静态工厂方式
OrderDao接口和OrderDaoImpl实现类
public interface OrderDao {
public void save();
}
public class OrderDaoImpl implements OrderDao {
public void save() {
System.out.println("order dao save ...");
}
}
OrderDaoFatory工厂类
//静态工厂创建对象
public class OrderDaoFactory {
public static OrderDao getOrderDao(){
System.out.println("factory setup....");
return new OrderDaoImpl();
}
}
applicationContext.xml配置
<!--方式二:使用静态工厂实例化bean-->
<bean id="orderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOrderDao"/>
AppForInstanceOrder测试类
public class AppForInstanceOrder {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
OrderDao orderDao = (OrderDao) ctx.getBean("orderDao");
orderDao.save();
}
}
3.实例工厂方式
UserDao接口和UserDaoImpl实现类
public interface UserDao {
public void save();
}
public class UserDaoImpl implements UserDao {
public void save() {
System.out.println("user dao save ...");
}
}
UserDaoFactory工厂类
//实例工厂创建对象
public class UserDaoFactory {
public UserDao getUserDao(){
return new UserDaoImpl();
}
}
applicationContext.xml配置
<!--方式三:使用实例工厂实例化bean-->
<bean id="userFactory" class="com.itheima.factory.UserDaoFactory"/>
<bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>
AppForInstanceUser测试类
public class AppForInstanceUser {
public static void main(String[] args) {
// //创建实例工厂对象
// UserDaoFactory userDaoFactory = new UserDaoFactory();
// //通过实例工厂对象创建对象
// UserDao userDao = userDaoFactory.getUserDao();
// userDao.save();
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) ctx.getBean("userDao");
userDao.save();
}
}
4.实现FactoryBean<T>方式【扩展,了解】
定义UserDaoFactoryBean实现FactoryBean<UserDao>
UserDaoFactoryBean中实例化什么类型的对象泛型就是该类型。
//FactoryBean创建对象
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
//代替原始实例工厂中创建对象的方法
public UserDao getObject() throws Exception {
return new UserDaoImpl();
}
public Class<?> getObjectType() {
return UserDao.class;
}
}
applicationContext.xml配置
<!--方式四:使用FactoryBean实例化bean-->
<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"/>
使用之前的AppForInstanceUser测试类去运行看结果就行了。注意配置文件id="userDao"是否重复。
五、Bean的生命周期
- 通过构造器或工厂方法创建bean实例;
- 为bean的属性赋值;
- 调用bean的初始化方法;
- 使用bean;
- 当容器关闭时,调用bean的销毁方法
五、依赖注入(DI配置)
1.setter方式注入
引用类型