文章目录
一、Spring框架
我们通常所说的 Spring 指的是Spring Framework (Spring框架) ,它是一个开源框架,有着活跃而庞大的社区,这就是它之所以能⻓久不衰的原因,Spring支持广泛的应用场景,它可以让 Java 企业级的应用程序开发起来更简单。
1.1 Spring Ioc容器
什么是容器?容器就是能装下许多东西的空间结构,例如图书架,能随时找到自己想要的书,而Spring也是一个容器,它是一个IoC容器。
什么是Ioc容器?
IoC = Inversion of Control 翻译成中文是 “ 控制反转 ” 的意思 , 也就是说Spring 是一个“控制反转”的容器。
1.2 控制反转
传统应用开发,比如我们现在要构建一辆车的程序,我们的开发流程可能是这样的
构建一辆车,车依赖车身,车身依赖底盘,底盘依赖轮胎。
传统开发代码示例如下,伪代码示例
public class NewCarExample {
public static void main ( String [ ] args) {
Car car = new Car (30);
car.init ();
}
/*
汽车对象
*/
private static class Car {
private Body body;
public Car(int size){
body = new Body(size);
}
public void init ( ) {
// 依赖⻋身
body.init();
}
}
/*
车身对象
*/
private static class Body{
private Bassplate bassplate;
public Body(int size){
bassplate = new Bassplate(size);
}
public void init(){
//依赖底盘
bassplate.init();
}
}
/*
车身底盘
*/
private static class Bassplate{
private Tire tire;
public Bassplate(int size){
tire = new Tire(size);
}
public void init(){
//依赖轮胎
Tire tire = new Tire();
}
}
/*
轮胎
*/
private static class Tire {
private int size ;
public Tire(int size) {
this.size = size;
}
public void init(){
System . out . println ( " 轮胎尺寸 : " + size);
}
}
}
在以上程序中,轮胎的尺寸是固定的,在开发需求量越来越大的时候,假如我们需要对轮胎尺寸进行修改,就需要对上述底层代码进行修改,上述底层代码修改之后,其他类的代码块也得面临修改的问题。一不小心就容易出错。
根据以上示例,我们改造一下上述代码,采用注入传递的方式
public class IocCarExample {
public static void main ( String [ ] args) {
Tire tire = new Tire ( 20);
Bassplate bassplate = new Bassplate ( tire);
Body body = new Body ( bassplate);
Car car = new Car (body);
car.run ();
}
static class Car {
private Body body ;
public Car ( Body body ) {
this.body= body;
}
public void run() {
body.init();
}
}
static class Body {
private Bassplate bassplate ;
public Body ( Bassplate bassplate) {
this.bassplate = bassplate;
}
public void init ( ) {
bassplate.init ();
}
}
static class Bassplate {
private Tire tire ;
public Bassplate ( Tire tire ) {
this.tire = tire;
}
public void init () {
tire.init();
}
}
static class Tire {
private int size ;
public Tire ( int size ) {
this.size = size;
}
public void init (){
System.out.println( " 轮胎 : " + size);
}
}
}
再来看实现逻辑
代码这样调整,无论底层类如何变化,其他类的代码不需要进行修改
我们发现了一个规律: 通用程序的实现代码 , 类的创建顺序是反的 , 传统代码是 Car 控制并创建了
Body, Body控制并创建了 Ballplate , 依次往下 , 而改进之后的控制权发生的反转,不再是上级对象创建并控制下级对象了 , 而是下级对象把注入将当前对象中 , 下级的控制权不再由上级类控制了 , 这样即使下级类发生任何改变 , 当前类都是不受影响的 , 这就是典型的控制反转 , 也就是 IoC 的实现思想 。
1.3 理解IoC
Spring 是包含众多工具方法的容器,我们如何理解容器这两个字,容器具备最基础的两个功能
- 把对象存入容器
- 从容器中取出对象
也就是说,spring最核心的功能,就是学习如何将对象存入容器中,再从spring中取出对象的方法。
将对象存放到容器中的好处: 将对象存储在 IoC 容器相当于将以后可能用的所有工具制作好都放到仓库中, 需要的时候直接取就行了, 用完再把它放回到仓库。 而 new 对象的方式相当于,每次需要工具了才实现,用完就扔掉了也不会保存,下次再用的时候还得重新实现, 这就是IoC 容器和普通程序开发的区别。
通过以上理解,我们可以认为我们就是把对象的创建和销毁的权利都交给 Spring 来管理了,它本身又具备了存储对象和获取对象的能力。
1.4 DI
说到 IoC 就得提到一个词就是 “ DI ” , DI 是 Dependency Injection 的缩写,翻译成中文是“依赖注入 ”的意思。所谓依赖注入 , 就是由IoC容器在运行期间 , 动态地将某种依赖关系注入到对象之中。所以,依赖注入 ( DI ) 和控制反转 (IoC) 是从不同的角度的描述的同一件事情 , 就是指通过引入 IoC容器 , 利用依赖关系注入的方式 , 实现对象之间的解耦。
也就说依赖注入是一种消除类之间依赖关系的设计模式。 例如,A类要依赖B类,A类不再直接创建B类,而是把这种依赖关系配置在外部xml文件(或java.config文件)中,然后由Spring容器根据配置信息创建、管理bean。
那么什么是Bean?Bean类如何注入Spring容器?
二 、Bean对象
2.1 什么是Bean?
- Bean被实例化的,是被Spring框架所管理的Java对象。
- Spring容器会自动完成Bean的实例化。将所创建的的Bean自动注入到Ioc容器中以供调用。
- 创建应用对象之间的协作关系的行为被称为:装配,这就是依赖注入的本质
2.2 maven的创建
1.首先在编译器中创建Maven项目,因为Spring是基于maven的。
2.项目依赖引入国内镜像源地址配置
由于maven默认引入依赖的地址是国外的地址,在引入依赖的时候可能会引入失失败,所以这里采用国内的镜像源地址
已经配置好的settings.xml文件:settings.xml
3.项目中添加依赖
在maven项目中添加对Spring的支持,粘贴之后刷新maven项目即可。
<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 bean的创建和使用
1.创建启动类测试
2.设置bean对象存储文件
文件以.xml结尾,文件名称取什么都可以,例如我这里叫javaconfig
配置文件如下:
<?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>
3.创建一个bean对象
package org.example.demo;
public class Car {
public void init(String name){
System.out.println("我是一辆车,我的品牌是"+name);
}
}
4.通过已经创建好的配置文件,注入Spring容器当中,注入格式如下
<bean id="car" class="org.example.demo.Car"></bean>
5.注入bean到spring容器中如何取出使用
-
想要从 Spring 中将Bean对象读取出来,先要得到 Spring 上下文对象,相当于得到了 Spring 容器。
-
再通过 spring 上下文对象提供的方法获取到需要使用的Bean对象,最后就能使用Bean对象了。
-
使用ApplicationContext就可以将容器中的对象取出来。
需要使用到的配置文件读取类
ClassPathXmlApplicationContext(常用) 加载类路径下的配置文件,要求配置文件必须在类路径下
6.通过上下文对象来取出bean对象并使用其中的方法
public class Test {
public static void main(String[] args) {
//得到上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("javaconfig.xml");
//根据id获取已经存入的bean对象
Car car = (Car) context.getBean("car");
//使用已经存入的bean
car.init("比亚迪");
}
}
运行结果如下:
7.通过bean工厂来取出其中的bean对象并使用
public class Test2 {
public static void main(String[] args) {
// 1. 得到 bean 工厂
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("javaconfig.xml"));
// 2. 获取 bean 对象 也是通过id获取
Car student = (Car) factory.getBean("car");
// 3. 使用 bean
student.init("哈哈哈哈");
}
}
运行结果如下
我们发现两种方式都可以取出bean对象,那么他们又有什么不同呢?
2.4 ApplicationContext VS BeanFactory
1.对比
- 继承关系和功能方面来说: Spring 容器有两个顶级的接口: BeanFactory 和 ApplicationContext。 其中 BeanFactory 提供了基础的访问容器的能力, 而 ApplicationContext 属于 BeanFactory 的子类, 它除了继承了 BeanFactory 的所有功能之外, 它还拥有独特的特性, 还添加了对国际化支持、 资源访问支持、以及事件传播等方面的支持。
- 性能方面来说: ApplicationContext 是一次性加载并初始化所有的 Bean 对象, 而 BeanFactory 是需要那个才去加载那个, 因此更加轻量。
简单来说,ApplicationContext是饿汉模式,一次性加载通过配置文件注入到容器的所有bean对象。BeanFactory 是懒汉模式,当你要使用某个bean的时候,他才会加载注入到容器的bean对象
结论验证:
我们再创建一个bean对象,并在已经创建后的bean对象里面加入构造方法
public class Car {
public Car(){
System.out.println("Car加载");
}
public void init(String name){
System.out.println("我是一辆车,我的品牌是"+name);
}
}
public class Person {
public Person() {
System.out.println("Person加载");
}
public void speak(){
System.out.println("我是一个人");
}
}
分别调用
public class Test3 {
public static void main(String[] args) {
//得到上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("javaconfig.xml");
System.out.println("=======================================================================");
//bean工厂
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("javaconfig.xml"));
}
}
结果:
结论验证成功。