Spring核心 and 创建使用
文章目录
- Spring核心 and 创建使用
- 一、Spring的定义
- 1.1什么是IoC
- 1.1.1 理解控制反转(IoC)
- 1.1.2 控制反转式程序开发
- 1.2 使用Spring IoC核心功能
- 2.1 DI的概念说明
- 二、Spring的创建和使用
- 2.1 创建一个Maven项目
- 2.2 添加Spring框架支持(依赖)
- 2.3 创建一个启动类(普通的类)和 main
- 三、将 Bean 存储到 Spring 容器中(重要)
- 3.1、 先创建一个 Bean
- 3.2.将 Bean 存储到 Spring 中(将 Bean 注册到容器)
- 四、获取并使用 bean对象
- ApplicationContext vs BeanFactory
- getBean()方法说明
- 五、Spring创建使用总结
本篇内容核心:
1、Spring 是什么,如何理解Spring
2、IoC和DI是什么,有什么区别?
3、Spring最核心的功能是什么?
一、Spring的定义
Spring Framework(Spring 框架)通常指的是 Spring,Spring是一个开源框架,有着活跃庞大的社区,Spring支持广泛的应用场景,他可以让java企业级的应用程序开发起来更简单。
1.1什么是IoC
Spring是一个容器,何为容器?(指用来容纳某种物品的装置)
- List/Map -> 数据存储容器;
- Tomcat -> Web容器
Spring是IoC的一个容器 ,IoC(Inversion of Control)“控制反转” ,也就是说Spring是一个 “控制反转” 的容器!!!
1.1.1 理解控制反转(IoC)
举一个栗子说明:
以构建一辆 车 的程序,传统的实现思路是:
构建一辆车首先 需要依赖车身,车身需要依赖底盘,底盘需要依赖轮胎;程序代码如下:
public class CarDemo {public static void main(String[] args) {Car car = new Car();car.run();}/*** 汽车对象*/static class Car {public void run() {// 需要依赖车身Framework framework = new Framework();framework.run();}}/*** 车身类*/static class Framework {public void run() {// 需要依赖轮胎Bottom bottom = new Bottom();bottom.run();}}/*** 底盘类*/static class Bottom {public void run() {// 依赖轮胎Tire tire = new Tire();tire.run();}}/*** 轮胎类*/static class Tire {// 尺寸private int size = 20;public void run() {System.out.println("轮胎尺寸:"+ size);}}
}
这上面的代码虽说可以实现这个车的构造,但是耦合性太强了,随时要依赖另一个对象,再者加上轮胎的需求尺寸是会越来越多,改变也会越来越频繁,然而上面的代码是固定尺寸,如果说需要修改尺寸,先看看修改尺寸的代码:
public class CarDemo {public static void main(String[] args) {Car car = new Car(30);car.run();}/*** 汽车对象*/static class Car {private Framework framework;public Car (int size) {// 需要依赖车身framework = new Framework(size);}public void run() {framework.run();}}/*** 车身类*/static class Framework {public Bottom bottom;public Framework (int size) {// 需要依赖轮胎bottom = new Bottom(size);}public void run() {bottom.run();}}/*** 底盘类*/static class Bottom {private Tire tire;public Bottom (int size) {// 依赖轮胎tire = new Tire(size);}public void run() {tire.run();}}/*** 轮胎类*/static class Tire {// 尺寸private int size;public Tire(int size) {this.size = size;}public void run() {System.out.println("轮胎尺寸:"+ size);}}
}
可见,一旦需要改需求那么整个程序都会受到影响,都要整体改一遍,增加工作量,增加错误率。
解决传统开发的缺陷:
其中重要的思想就是 解藕 。由上面代码可知,我们在每个类里面都创建了下级类,当发生需求改变,就会整个代码改变;此时我们只需要将原来自己创建下级类,改为传递的方式(注入的方式),如果需求改变,就不需要在当前类中创建修改下级类,故下级类即使发生改变也不需要在当前类本身上面修改,这样就可以完成 “解耦”
1.1.2 控制反转式程序开发
基于以上思想 “解耦” ,我们把创建子类的方式,改为注入传递的方式,具体代码如下:
public class CarDemo {public static void main(String[] args) {Tire tire = new Tire(40);Bottom bottom = new Bottom(tire);Framework framework = new Framework(bottom);Car car = new Car(framework);car.run();}/*** 汽车对象*/static class Car {private Framework framework;public Car (Framework framework) {this.framework = framework;}public void run() {framework.run();}}/*** 车身类*/static class Framework {public Bottom bottom;public Framework (Bottom bottom) {this.bottom = bottom;}public void run() {bottom.run();}}/*** 底盘类*/static class Bottom {private Tire tire;public Bottom (Tire tire) {this.tire = tire;}public void run() {tire.run();}}/*** 轮胎类*/static class Tire {// 尺寸private int size;public Tire(int size) {this.size = size;}public void run() {System.out.println("轮胎尺寸:"+ size);}}
}
经过了代码的调整,无论底层如何变化,中间的程序都没有发生任何改变,这样就可以完成解耦,让需求,程序更加灵活了。
对比总结:
传统代码对象创建顺序是:car->Framework->Bottom->Tire
改进之后解耦代码对象创建顺序:Tire->Bottom->Framework->car
现在就可以发现一个规律,类的创建是相反的,经过解耦的改变,控制权发生了改变,之前的控制权是以车car为主,现在是先以轮胎Tire为主;不再是上级对象创建控制下级对象,而是下级对象把需求注入将 当前对象中 ,这样下级的控制权不再是上级控制了,即使下级类发生了改变,当前类也不会受影响的,这就是典型的“控制反正(IoC)”,也就是IoC的实现思想。
1.2 使用Spring IoC核心功能
Spring最核心的总结:Spring是包含了多个工具方法的IoC容器 。
❓❓如何理解“Spring 是一个IoC(控制反转) 容器”
重点还是在 容器 二字,这个容器具有两个最基础的功能。
- 将对象存入容器中;{存}
- 从容器中取出对象;{取}
那么学Spring最核心的功能,就是学如何将对象存入Spring中,再从Spring中获取对象的过程
好处:
- 将对象存储在IoC容器相当于将以后可能用到的所有工具制作好放入仓库中。
- 需要的时候再出来拿,用完后再放回去
new对象相当于纯手工制作,每次需要工具现做,用完扔掉也不会保存,下次用还要重新做,很麻烦。这就是IoC容器和普通重新开发的区别。
📖📖最后总结:
Spring是一个IoC容器,对象的创建和销毁的权利都交给Spring来管理,它本身又具备了存储对象和获取对象的能力
2.1 DI的概念说明
DI(Dependency Injection),翻译成中文是**“依赖注入” ** ;依赖注入,就是由IoC容器在运行期间,动态的将某种依赖关系注入到对象之中。指通过引入IoC容器,利用依赖关系注入的方式,实现对象之间的“解耦”。
乍一看 DI和IoC好像说的是同一件事情,实则从不同角度来描述的同一件事情。
就好比日常生活中的内存,大家都说手机内存256G或者说128G,实则说的是手机总的外存储容量,内存是指运行内存一般是8G或者16G。
- 广义:IoC=DI 从不同角度来描述同一件事情
- 微观:IoC描述的是目标,DI描述的是具体可实现的思路
栗子:
目标指:晚上出去是去吃好吃的。
可实现的思路指:海底捞,火锅,烧烤…
这篇文章重点(也是面试容易问的):
1、Spring是什么,如何理解Spring
答:Spring是包含众多工具方法的IoC容器。
2、IoC和DI是啥,有什么区别
答:IoC是“控制反转”,DI是“依赖注入”
3、Spring最核心的功能是什么?
答:具备了存储对象和获取对象的能力(存,取)。
二、Spring的创建和使用
2.1 创建一个Maven项目
2.2 添加Spring框架支持(依赖)
在项目pom.xml 中添加Spring框架的支持
重要的依赖:
- spring-context (上下文)
- spring-beans (管理对象模块)
xml配置如下:
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.3.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>5.2.3.RELEASE</version></dependency>
</dependencies>
2.3 创建一个启动类(普通的类)和 main
三、将 Bean 存储到 Spring 容器中(重要)
3.1、 先创建一个 Bean
Bean 也称为 “对象” ,提到Bean就是对象的意思。
就是创建一个对象:
3.2.将 Bean 存储到 Spring 中(将 Bean 注册到容器)
a)、在 Maven项目中的resources 底下创建一个 xxx(名字可以随意取).xml
里面Spring的配置文件是可以保存的,是固定格式,保存到自己能找到的地方
<?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>
b)、在xml中添加一个 bean,就是将刚刚创建的User对象注册到Spring中,具体操作是在 中添加。
这里面有两个重要的属性:
- id:是在spring中的一个身份标识,之后就是用这个身份标识完成代码
- class:指存储对象的路径,一般是完整包名+类名
到这里就是Spring Ioc容器里面核心重要的一个“存”操作
四、获取并使用 bean对象
ApplicationContext获取上下文
1、获取Spring 上下文对象。对象都交给了Spring管理,故获取对象要从Spring中获取,那么首先需要先创建Spring上下文,再得到Spring上下文。
//1 .创建上下文需要配置spring配置信息(得到 Spring上下文)ApplicationContext applicationContext =new ClassPathXmlApplicationContext("spring.xml");
2、使用上下文对象获得一个bean。
User user = (User) applicationContext.getBean("user");//根据 bean id来获取
这段代码没有 new 对象,是从Spring里面拿出的bean,这里就体现了Spring的价值了
3、使用 bean
user.对象的方法;
BeanFactory获取上下文
这是获取 Spring 上下文的第二种方法
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring.xml"));
里面的参数也是与 resources 里面的xml对应的,这是最古老的方式。
BeanFactory beanFactory1 = new ClassPathXmlApplicationContext("spring.xml");
用 ClassPathXmlApplicationContext
也是可以的
💀💀💀完整代码:
public class App {public static void main(String[] args) {//第二种获取Spring 上下文的方法是 BeanFactoryBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring.xml")); //这是最古老的方式User user = (User) beanFactory.getBean("user");user.saihi();}
}
尽然都是一样的获取上下文对象,那他们的区别又是哪里尼?
ApplicationContext vs BeanFactory
**1、**性能方面:ApplicationContext 是 一次性加载并初始化 xml 里面所有 bean 对象(在当前的 Spring 项目里面);BeanFactory 是按需求进行初始化(按照代码的调用,getBean(bean id))。故ApplicationContext 就会初始化慢,但是调用快(都初始化好了直接取出就行),BeanFactory 初始化快,但是调用慢。
ApplicationContext applicationContext =new ClassPathXmlApplicationContext("spring.xml"); // 创建并初始化所有 bean 对象
ApplicationContext 在这里就已经创建并初始化所有 bean 对象。
BeanFactory beanFactory1 = new ClassPathXmlApplicationContext("spring.xml");
User user = (User) beanFactory.getBean("user"); //真正创建 User 对象
BeanFactory 在下一步去 getBean 的时候采取创建对象。
**2、**二者的归属关系不同:ApplicationContext 输入 BeanFactory 的子类。
3、 二者的功能不同:BeanFactory 提供了基础操作 Bean 访问容器的功能: ApplicationContext 继承了BeanFactory,它除了有操作 Bean 的基础功能之外,还提供了更多的功能,如国际化的支持,事件的传播,资源访问等功能。
总结:“取”操作
getBean()方法说明
getBean() 主要有三种使用的方法:
- getBean(String s)----------- Object
- getBean(class aClass)------------------T
- getBean(String s, Class aclass)-----------------T
- 第一种是根据 bean id 获取的 Object 对象 (需要类型的强转)。对应代码:
User user = (User) beanFactory.getBean("user");
- 第二种是根据类型获取 bean ,无需强装类型。对应代码:
User user = beanFactory.getBean(User.class);
特点:写法简单,但是如果 Spring 里面将一个对象注入多次,那么使用此方法就会导致程序异常。
- 第三种指的是 bean id ,还有bean类型 ☆☆☆☆
User user = beanFactory.getBean("user",User.class);
这种方法就解决了上面两种方法的缺点,不用强转类型,也不用担心一个对象在 Spring 里面注入多次而报错,大多数使用的就是第三种方法。