Spring 6【Spring Framework中的IoC/DI、IoC/DI的优缺点 、第一个Spring Framework 案例】(二)-全面详解(学习总结---从入门到深化)

目录

3.Spring Framework中的IoC/DI

4.IoC的具体实现框架有哪些

5.IoC/DI的优缺点 

6. IoC/DI在项目中具体应用场景

四、BeanFactory和ApplicationContext 

五、第一个Spring Framework 案例


3.Spring Framework中的IoC/DI

既然要学习一下Spring Framework中对IoC/DI原则的实现,我们无论怎么说都没有官方文档权威。

Spring Framework 官方文档对IoC的解释如下,网址: https://docs.spring.io/spring-framework/doc s/current/reference/html/core.html#spring-core 

1、从Spring Framework官方文档对IoC 容器的解释上可以看出来,如下几点:

2、强调IoC也叫做DI。(IoC is also known as dependency injection(DI))

3、官方为了防止IoC 和 IoC Container 名称混淆。更多以DI作为第一名称。而容器叫做IoC Container(IoC容器)

4、强调IoC绝对不是由IoC容器实例化对象这一点,而是一个过程(process)。从IoC 容器实例化对象, 一直到在IoC容器内部注入对象依赖的其他对象的过程。

5、IoC容器实例化对象时有两种方式:通过构造方法和通过工厂设计模式。

6、Spring中使用BeanFactory和ApplicationContext作为IoC容器的接口类型。ApplicationContext是 BeanFactory的子接口,功能更加强大。

7、IoC容器内部管理的所有对象统称beans,其中单个对象叫做bean。 

下图是官方对DI的解释,网址: https://docs.spring.io/spring-framework/docs/current/reference/ht ml/core.html#beans-factory-collaborators

从Spring Framework官方文档对DI的解释上可以看出来,如下几点:

1、强调DI也叫做IoC(hence the name,Inversion of Control)。

2、DI是一个过程(process),绝对不是把对象注入到另外一个对象就是DI。其解释和IoC一样,是从 实例化对象,到把对象注入到另外对象的过程就是DI。

3、使用DI可以实现对象解耦,让代码更加清晰。不再需要管理自己所依赖的对象,也不需要知道依赖项 的位置和类型。(第二大段英文)

4、DI有两种实现方式:构造注入(Constructor-based dependency injection)和设值注入(Setter-based dependency injection) 

4.IoC的具体实现框架有哪些

Java 体系对IoC做具体实现的框架:

轻量级:Spring Framework 、Guice、 Pico Container、 Avalon、 HiveMind

重量级:EJB

.Net 体现对IoC做具体实现的框架:

Spring.net、 Autofac 、Castle Windsor 、Unity

上面这些内容有一些可能十年老Java程序员都没有听说过。对于小伙伴们,我们只要掌握好Java领域, 使用最多的IoC实现框架,Spring Framework就可以了。

5.IoC/DI的优缺点 

优点:

1、解耦。对象的实例化、组装、管理完全交给IoC容器。实现对象之间的解耦。

2、适合中大型项目。对于复杂的项目,里面对象关系可能比较复杂,IoC 容器可以很好的管理这 些对象。

缺点:

1、对象交给容器实例化和注入的过程都是反射(reflect)。反射相对硬编码实例化有一定性能损 耗。好在在一些需要频繁实例化的场景中,Spring Framework可以借助单例设计模式来减少 bean实例化的次数。

2、不适合微、小型项目。为了对象解耦,在对象关系不复杂的情况下,额外需要大量的XML配置 或注解,增加了工作量。

6. IoC/DI在项目中具体应用场景

IoC/DI 主要作用就是管理对象的实例化和对象之间依赖关系。项目中以前需要自己实例化的层对象、需 要自己实例化框架或工具包的入口类都可以交给Spring 容器进行管理。

1、层对象:Java项目都是分层开发。通过IoC容器管理所有层对象,可以在其他被IoC容器管理的对象 随时随地的注入这些层对象。例如:PeopleMapper 接口代理对象、PeopleDaoImpl、 PeopleServiceImpl

2、整合其他技术:可以通过IoC容器管理其他技术的入类。在启动IoC容器时,管理Bean。如: MyBatis中的SqlSessionFactory和SqlSession等

下图中对应普通类PeopleMapper、PeopleServiceImpl这些不同层中普通都可以交给Spring容器进行管 理。放入到容器中的对象可以相互直接依赖。但是Servlet只能被Tomcat管理(由Tomcat帮助实例化创 建的),所以Spring容器是无法管理Servlet的。但是Servlet可以从Spring容器中取出对象。

四、BeanFactory和ApplicationContext 

IoC/DI 实现过程非常重要的一块就是IoC Container。必须创建出IoC容器,才能继续做后面的事情。 在Spring框架中IoC Container的类型是BeanFactory和ApplicationContext。所以必须先搞懂这两个东西是什么,然后才能去写第一个Spring框架案例。否则即使照着视频写出来了,也是照葫芦画瓢。 在上面学习IoC/DI时,就看到官方在介绍IoC时直接介绍了BeanFactory和ApplicationContext的区别。

网址: https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-int roduction

整理一下:

1. BeanFactory是Spring框架中IoC容器的顶级接口。里面提供了IoC容器的最核心功能。

2. ApplicationContext是BeanFactory的子接口,ApplicationContext具备BeanFactory的所有功 能。

3. ApplicationContext比BeanFactory多的功能

* AOP 功能

* 国际化(MessageSource)

* 访问资源,如URL和文件(ResourceLoader)

* 消息发送机制(ApplicationEventPublisher)

* Spring集成Web时功能。 

除上述文档直接给出的两者区别外,使用BeanFactory时,默认所有的bean都是获取时才会被实例化。 而使用ApplicationContext时IoC 容器启动就会立即实例化所有bean。 这时有的小伙伴可能有点迷惑了,那到底用哪个接口作为IoC容器类型呢?其实这个问题官方已经给出明 确的解释了。

网址: https://docs.spring.io/spring-framework/docs/current/reference/html/core.ht ml#context-introduction-ctx-vs-beanfactory 

官方已经明确说明了,推荐使用ApplicationContext,所以我们后面都是用ApplicationContext或其子 接口。 虽然不推荐使用BeanFactory,但是我们可以看看BeanFactory接口里面到底有哪些方法。 

从上图看到,BeanFactory里面主要功能就是获取容器中的Bean。获取时可以按照类型获取,也可以按 照名称获取,还支持泛型,可以控制获取后Bean的类型。所以BeanFactory只提供了IoC容器的最基本 功能。即:IoC/DI功能。

BeanFactory的层次结构(Hierarchy)中相关接口和实现类比较多 

所以我用一张更加清晰的图来表示下这两个接口及常用的实现类。

可以看出来,ApplicationContext要比BeanFactory多继承了6个父接口。这六个父接口就是 ApplicationContext比BeanFactory多出的功能。虽然现在看不太懂这6个接口是什么意思,也不用着 急,等学到后面再回头来看就可以了,现在只需要知道ApplicationContext比BeanFactory功能更加强大就可以了。

最后来看看ClassPathXmlApplicationContext。因为ApplicationContext是接口,是无法实例化。只能实例化这个实现类。想要实例化类,就需要调用类的构造方法。下图被选中具有一个String类型参数的 构造方法就是我们常用的,参数是Spring框架配置文件路径。 

然后就可以通过从BeanFactory继承过来的getBean获取到容器中的Bean对象了。

所以,想要在Spring框架中创建IoC容器,并从容器中获取到Bean,代码也比较简单

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
People peo = applicationContext.getBean("peo", People.class);
System.out.println(peo);

 最后附上BeanFactory容器创建的方式。

Spring 3.1之前BeanFactory实例化是通过XmlBeanFactory,但是XmlBeanFactory在目前的Spring Framework 6已经不存在。

FileSystemResource fsr = new
FileSystemResource("D:\\idea\\idea2022ws\\summer\\src\\main\\resources\\applicat
ionContext.xml");
XmlBeanFactory xmlBeanFactory = new XmlBeanFactory(fsr);
People peo = xmlBeanFactory.getBean("peo",People.class);
System.out.println(peo);

 从Spring 3.1 版本开始,使用DefaultListableBeanFactory和XMLBeanDefinitionReader替代了上面写法。

DefaultListableBeanFactory defaultListableBeanFactory = new
DefaultListableBeanFactory();
XmlBeanDefinitionReader xmlBeanDefinitionReader = new
XmlBeanDefinitionReader(defaultListableBeanFactory);
xmlBeanDefinitionReader.loadBeanDefinitions(new
FileSystemResource("D:\\idea\\idea2022ws\\summer\\src\\main\\resources\\applicat
ionContext.xml"));
People peo = defaultListableBeanFactory.getBean("peo", People.class);
System.out.println(peo);

五、第一个Spring Framework 案例

任何框架从建立项目到测试结果都分为下面5个步骤,这5个步骤属于公式。避免写代码没有思路。

Spring框架不依赖于Servlet容器(Tomcat),所以使用非模板的普通Maven项目就可以了。 Spring框架提供了XML、注解、Java Config三种方式进行项目配置。首先我们从XML方式开始学习。

1.创建项目,并添加依赖 

创建普通Maven项目,并命名为summer(既然Spring框架叫春天,我们就叫夏天)

在项目的pom.xml中添加Spring项目的最基本依赖。

Spring项目想要运行起来必须包含:

1、spring-context.jar。spring上下文依赖,它依赖了下面的四个jar。

2、spring-core.jar。Spring 核心jar包。它依赖了spring-jcl.jar

3、spring-aop.jar。Spring AOP基本支持。(不是必须的)

4、spring-expression.jar。Spring的表达式语言支持。

5、spring-beans.jar。Spring容器的bean管理。

6、spring-jcl.jar。Spring 4版本时是common-logging.jar。从5开始Spring自己对日志进行了封装。 

所以在Maven中想要使用Spring框架只需要在项目中导入spring-context就可以了,其他的jar包根据 Maven依赖传递性都可以导入进来。 在文档制作时Spring框架最新版本为6.0.6。所以下面依赖导入最新的6.0.6版本。 spring-context坐标可以去 https://mvnrepository.com/ 中搜索 spring-context

<dependencies>
   <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>6.0.6</version>
   </dependency>
</dependencies>

在项目的pom.xml中添加完依赖后,需要手动更新下:

关于Spring框架版本号说明: 从Spring框架5.3.0 开始,Spring 所有子模块版本号中不再以.RELEASE结尾。 例如:之前是5.2.22.RELEASE 例如:现在是6.0.6 

2.随意创建一个类 

在项目下创建一个类作为测试Spring IoC/DI功能的类。

示例中叫做com.tong.pojo.People

public class People {
private int id;
private String name;
// 没有粘贴getter/setter、toString、无参构造方法、全参构造方法
}

3.创建Spring配置文件

在src/main/resources下鼠标右键-> New -> XML Configuration File -> Spring Config。 一定要注意:只有正确的添加spring-context依赖,才会有这项。

小提示: 文件名称没有强制要求。官方示例中配置文件名称叫做applicationContext.xml,所以我们也把 Spring配置文件叫做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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- id:bean的名称 class:类型全限定路径 -->
<bean id="peo" class="com.tong.pojo.People"></bean>
</beans>

 3.1 创建Spring Config后提示项目没有这个配置文件,解决办法

当文件创建完成后在上面提示“Application context not configured for this file” 。其实这个问题不影响 程序的运行。但是如果小伙伴们非得纠结这个问题,我们也可以解决这个问题。

第一种方式:手动更改项目配置(Reload 后失效) 

选择IDEA 菜单 File -> Project Structure...

按照图示,添加配置文件。 Modules -> 项目名(summer)下的Spring -> 点击 +

把配置文件勾选上后,先点Apply,再点击OK按钮

然后去修改applicationContext.xml内容,发现上面警告信息没有了。

第二种方式:快捷方式(Reload 后失效) 

直接点击提示信息:Configure application context -> Create new application context

弹出框和上面手动配置时,添加配置文件的弹出框一样。只是这里自动就把配置文件选上了。直接点击 下面OK按钮就可以了。

第三种方式:创建配置文件模板(Reload 后失效) 

如果不想要创建文件后有警告信息,也可以创建配置文件模板

(1)把XML文件的文档头和 标签复制。不要里面的标签

(2)点击IDEA菜单中第一个 File -> Settings...

(3)按图填写模板

Name:是模板名。以后通过这个名称来找到模板内容。

Extension:文件扩展名。创建文件时可以以.xml结尾,如果没有.xml结尾,IDEA会帮助添加上。 

 

彻底解决方案(reload后依然生效) 

 直接点击警告信息,右侧的小螺丝图标,在弹出框中点击第一个“Edit inspection profile setting”

在弹出框中,取消"Incorrect XML application context"勾选,然后点击OK。这时无论是修改XML文件 内容。还是Reload项目,都不在弹出警告信息

因为没有警告信息了,所以无法再次点击警告的螺丝图标。 想要找到上图界面,需要通过:IDEA菜单 File -> Editor -> Inspections -> Spring -> Spring Core -> Setup找到 

4.创建测试类

创建测试类,测试Spring功能。 

package com.tong.test;
import com.tong.pojo.People;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
    public static void main(String[] args) {
    // IoC: 对象实例化和给对象注入依赖内容的过程都交给IoC容器完成的过程。
    // 拆分讲解:先讲解如果让IoC容器对类实例化。
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    /*
    getBean():
    第一个参数:IoC容器中Bean的ID
    第二个参数:返回值类型。没有第二个参数返回值为Object类型
    */
    People peo = ac.getBean("peo", People.class);
    System.out.println(peo);
   }
}

5.观察结果

发现People对象可以成功创建,但是对象中的所有属性没有赋值

猜你喜欢

转载自blog.csdn.net/m0_58719994/article/details/131748941
今日推荐