iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >如何理解SpringFramework与IOC依赖查找
  • 508
分享到

如何理解SpringFramework与IOC依赖查找

2023-06-15 19:06:03 508人浏览 安东尼
摘要

这篇文章主要介绍“如何理解springFramework与ioc依赖查找”,在日常操作中,相信很多人在如何理解SpringFramework与ioC依赖查找问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理

这篇文章主要介绍“如何理解springFramework与ioc依赖查找”,在日常操作中,相信很多人在如何理解SpringFramework与ioC依赖查找问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理解SpringFramework与IOC依赖查找”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

1. 谈谈SpringFramework / 说说你理解的SpringFramework

SpringFramework 是一个开源的、松耦合的、分层的、可配置的一站式企业级 Java 开发框架,它的核心是 IOC 与 aop  ,它可以更容易的构建出企业级 Java 应用,并且它可以根据应用开发的组件需要,整合对应的技术。

松耦合的: 为了描述IOC和AOP, 可能会延伸出IOC松耦合相关内容 可配置: 给后面的SpringBoot(约定大于配置)做铺垫 IOC 与 AOP:  Inverse of Control 控制反转、Aspect Oriented Programming 面向切面编程

2. 为何使用SpringFramework

可通过如下几点进行描述:

IOC 实现了组件之间的解耦

AOP 切面编程将应用业务做统一或特定的功能增强, 可实现应用业务与增强逻辑的解耦

容器管理应用中使用的Bean、托管Bean的生命周期、事件与监听的驱动机制

WEB事务控制、测试、与其他技术的整合

3. SpringFramework包含哪些模块?

  • beans、core、context、expression 【核心包】

  • aop 【切面编程】

  • jdbc 【整合 jdbc 】

  • ORM 【整合 ORM 框架】

  • tx 【事务控制】

  • web 【 Web 层技术】

  • test 【整合测试】

  • ......

4. 依赖查找与依赖注入的对比

如何理解SpringFramework与IOC依赖查找

5. BeanFactory与ApplicationContext的对比

BeanFactory 接口提供了一个抽象的配置和对象的管理机制,

ApplicationContext 是 BeanFactory 的子接口,它简化了与 AOP 的整合、消息机制、事件机制,以及对 Web 环境的扩展(  WebApplicationContext 等)

ApplicationContext 主要扩展了以下功能:

  • AOP 的支持( AnnotationAwareAspectJAutoProxyCreator 作用于 Bean 的初始化之后 )

  • 配置元信息( BeanDefinition 、Environment 、注解等 )

  • 资源管理( Resource 抽象 )

  • 事件驱动机制( ApplicationEvent 、ApplicationListener )

  • 消息与国际化( LocaleResolver )

  • Environment 抽象( SpringFramework 3.1 以后)

2.  SpringFramework发展史

在Spring技术之前,J2EE兴起,当时的J2EE学习成本极高,开发速度慢,开发出来的程序性能消耗也高,已经跟不上当时应用程序的需要。在2002  年,Rod Johnson写了一本书名为《Expert One-on-One J2EE design and development》 ,书中对当时现有的  J2EE 应用的架构和EJB框架存在的臃肿、低效等问题提出了质疑,并且积极寻找和探索解决方案。

基于普通Java类和依赖注入的思想提出了更为简单的解决方案,这便是Spring框架核心思想的萌芽

过了 2 年,2004 年 SpringFramework 1.0.0 横空出世,随后 Rod Johnson 又写了一本书**《Expert  one-on-one J2EE Development without EJB》**,当时在 J2EE  开发界引起了巨大轰动,这本书中直接告诉开发者完全可以不使用 EJB 开发 J2EE 应用,而是可以换用一种更轻量级、更简单的框架来代替,那就是  SpringFramework 。

那时在开发界是种种的质疑,大概是这样的,纳尼? 质疑IBM诸多大佬的设计精华,这个是什么人?为何如此嚣张? 而后  还是被一些开发者尝试使用了,使用后发现确实要比EJB好用,不那么臃肿,性能也有所改善,提供的一些特性也优于EJB,于是就慢慢转投SpringFramework

下面展示下SpringFramework重要版本的更新时间及主要特性

如何理解SpringFramework与IOC依赖查找

3. IOC依赖查找

基础框架搭建

创建Maven模块,这里以ioc-learning为例

引入依赖

<dependency>     <groupId>org.springframework</groupId>     <artifactId>spring-context</artifactId>     <version>5.2.8.RELEASE</version> </dependency>

创建配置文件 ioc-learning-dl.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">        </beans>

声明普通类Person.java

public class Person { }

ioc-learning-dl.xml配置文件加入Persion的声明

<bean id="person" class="com.huodd.bean.Person"></bean>

创建启动类

public class DlApplication {     public static void main(String[] args) {         // 读取配置文件  使用接口 BeanFactory 接收          BeanFactory factory = new ClassPathXmlApplicationContext("dl/ioc-learning-dl.xml");         // 通过配置文件中声明的 id 进行对象的获取         Person person = (Person) factory.getBean("person");         System.out.println(person);     } }

运行打印

com.huodd.bean.Person@57baeedf

成功打印出 Person 的全限定类名 + 内存地址,证明编写成功。

3.1 byName 名称查找

上述基础框架中的步骤6

核心代码

Person person = (Person) factory.getBean("person");

3.2 byType 类型查找

普通类

修改配置文件 ioc-learning-dl.xml 将person的声明中id属性去掉

<bean class="com.huodd.bean.Person"></bean>

修改启动类

public static void main(String[] args) {         BeanFactory factory = new ClassPathXmlApplicationContext("dl/ioc-learning-dl.xml"); //        Person person = (Person) factory.getBean("person");         Person person = factory.getBean(Person.class);         System.out.println(person);     }

getBean方法参数中直接传入Class类型 返回值也无需再进行强转

运行main方法 打印如下

com.huodd.bean.Person@61862a7f

接口

创建接口demoDao 以及 实现类 DemoDaoImpl

public interface DemoDao {     List<String> findAll(); }  public class DemoDaoImpl implements DemoDao{     @Override     public List<String> findAll() {         return Arrays.asList("user1", "user2", "user3");     } }

修改配置文件 ioc-learning-dl.xml 加入 DemoDaoImpl的声明

<bean class="com.huodd.dao.DemoDaoImpl"></bean>

修改启动类

public static void main(String[] args) {        BeanFactory factory = new ClassPathXmlApplicationContext("dl/ioc-learning-dl.xml");        DemoDao demoDao = factory.getBean(DemoDaoImpl.class);        System.out.println(demoDao);        System.out.println(demoDao.findAll());    }

运行main方法 打印结果如下

com.huodd.dao.DemoDaoImpl@7334aada [user1, user2, user3]

由此可见 DemoDaoImpl 注入成功 并且BeanFactory可以根据接口类型找到对应的实现类

3.3 高级查找

ofType 根据类型查找多个

如果一个接口有多个实现类,如何一次性的把所有的实现类都取出来呢? 前面用到的getBean方法显然无法满足 需使用到ofType方法

继上面的代码 创建2个DemoDao的实现类 如下

public class DemoMysqlDaoImpl implements DemoDao {     @Override     public List<String> findAll() {         return Arrays.asList("Mysql_user1", "mysql_user2", "mysql_user3");     } } public class DemooracleDaoImpl implements DemoDao {     @Override     public List<String> findAll() {         return Arrays.asList("oracle_user1", "oracle_user2", "oracle_user3");     } }

修改配置文件 ioc-learning-dl.xml 加入新建的两个实现类的声明

<bean class="com.huodd.dao.impl.DemoMysqlDaoImpl"></bean> <bean class="com.huodd.dao.impl.DemoOracleDaoImpl"></bean>

修改启动类

public static void main(String[] args) {         ApplicationContext ctx = new ClassPathXmlApplicationContext("dl/ioc-learning-dl.xml");         Map<String, DemoDao> beans = ctx.getBeansOfType(DemoDao.class);         beans.forEach((beanName, bean) -> {             System.out.println(beanName + " : " + bean.toString());         });      }

运行main方法 打印结果如下

com.huodd.dao.impl.DemoMysqlDaoImpl#0 : [mysql_user1, mysql_user2, mysql_user3] com.huodd.dao.impl.DemoOracleDaoImpl#0 : [oracle_user1, oracle_user2, oracle_user3]

细心的小伙伴可能会发现 为何这里读取配置文件的返回值使用的是ApplicationContext 而不使用BeanFactory

ApplicationContext 也是一个接口,通过idea的diagram查看类的继承链,可以看到该接口继承了BeanFactory

官方文章中有这样的解释:

org.springframework.beans 和 org.springframework.context 包是 SpringFramework 的  IOC 容器的基础。BeanFactory 接口提供了一种高级配置机制,能够管理任何类型的对象。ApplicationContext 是 BeanFactory  的子接口。它增加了:

  • 与 SpringFramework 的 AOP 功能轻松集成

  • 消息资源处理(用于国际化)

  • 事件发布

  • 应用层特定的上下文,例如 Web 应用程序中使用的 WebApplicationContext

如此说来 ApplicationContext 包含了 **BeanFactory 的所有功能,**并且还扩展了更多的特性

其实对于我们目前的最主要原因是BeanFactory 中木有getBeansOfType()这个方法~~~

withAnnotation 根据注解查找

IOC 容器还可以根据类上标注的注解来查找对应的 Bean

创建一个注解类

@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface animal { }

创建几个bean对象

@Animal public class Dog { }  @Animal public class Cat { }  public class Xiaoming { }

其中只有Xiaoming这个类没有添加@Animal注解

修改XML配置文件,添加如下三个声明

<bean id="dog" class="com.huodd.bean.Dog"></bean> <bean id="cat" class="com.huodd.bean.Cat"></bean> <bean id="xiaoming" class="com.huodd.bean.Xiaoming"></bean>

修改启动类

public class DlApplication {     public static void main(String[] args) {         ApplicationContext ctx = new ClassPathXmlApplicationContext("dl/ioc-learning-dl.xml");         Map<String, Object> beans = ctx.getBeansWithAnnotation(Animal.class);         beans.forEach((beanName, bean) -> {             System.out.println(beanName + " : " + bean);         });     } }

运行main方法 打印结果如下

dog : com.huodd.bean.Dog@313ac989 cat : com.huodd.bean.Cat@4562e04d

延迟查找

对于一些特殊场景,需要依赖容器中某些特定的bean 但是当他们不存在时如何使用默认/或者缺省策略来处理逻辑呢?

这里我们先把xml配置文件中的 Dog 的声明暂时删掉

这样我们在获取dog的时候ctx.getBean(Dog.class)就会报错

NoSuchBeanDefinitionException

现有方案启用缺省策略

Dog dog; try {     dog = ctx.getBean(Dog.class); } catch (NoSuchBeanDefinitionException e) {     // 找不到Dog时手动创建     dog = new Dog(); } System.out.println(dog);

这里我们把业务代码写在了catch代码块中,不够优雅,性能也有待改善,而且如果后期每个bean都这样处理,代码量巨大

改造下 获取之前检查

Dog dog = ctx.containsBean("dog") ? (Dog) ctx.getBean("dog") : new Dog();

这里使用到了ApplicationContext中的方法 containsBean 用于检查容器中是否有指定的bean

该方法看似已经没有问题了,但是要考虑到该方法传递的参数只能传递bean的id 不能按照bean的类型去查找  如果bean的名字是其他的呢,工作量还是巨大的

使用延迟查找

该机制的大概思路为 当我们想要获取一个Bean的时候,先返回给我们一个包装类,等到我们真正去使用的时候再去“拆包”检查里面到底有没有该Bean对象

使用方法如下

ObjectProvider<Dog> dogProvider = ctx.getBeanProvider(Dog.class);

上面代码可以看到 就是按照前面的思路进行处理的,返回了一个“包装”给我们,当我们使用的时候直接调用getObject方法

但如果 容器中没有该Bean 还是会报 NoSuchBeanDefinitionException  ,下面会介绍下ObjectProvider提供的其他方法

  • getIfAvailable()该方法可以在找不到Bean的时候返回null 而不抛出异常

可以使用如下方法实现

Dog dog = dogProvider.getIfAvailable(Dog::new);
  • ifAvailable()该方法是在取到Bean后马上或者间歇的使用

代码如下

dogProvider.ifAvailable(dog -> System.out.println(dog)); // 或者使用方法引用

到此,关于“如何理解SpringFramework与IOC依赖查找”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: 如何理解SpringFramework与IOC依赖查找

本文链接: https://www.lsjlt.com/news/281304.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何理解SpringFramework与IOC依赖查找
    这篇文章主要介绍“如何理解SpringFramework与IOC依赖查找”,在日常操作中,相信很多人在如何理解SpringFramework与IOC依赖查找问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理...
    99+
    2023-06-15
  • 如何理解IoC的依赖注入
    这篇文章主要讲解了“如何理解IoC的依赖注入”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何理解IoC的依赖注入”吧! 一、注解驱动IoCxml...
    99+
    2022-10-19
  • idea如何查找maven依赖、查看依赖关系、删除重复的jar包
    一 先装一个管理pom依赖的插件 File–>Settings–>Plugins–>搜索maven–>找到Maven Helper安装–>重启idea 打开pom.xml剔除重复的包 1 选择Dep...
    99+
    2023-09-30
    intellij-idea jar java
  • maven找不到依赖如何解决
    当Maven找不到依赖时,可以尝试以下几个解决方案:1. 检查依赖的版本和命名:确保依赖的版本和命名与Maven中的配置一致。可以通...
    99+
    2023-08-26
    maven
  • linux如何查找软件包得依赖关系
    这篇文章主要介绍linux如何查找软件包得依赖关系,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!apt-cache是一个apt软件包管理工具,它可查询apt的二进制软件包缓存文件。通过它我们可查询软件包的状态信息。a...
    99+
    2023-06-05
  • Spring与Python集成:如何管理NPM依赖?
    随着前端技术的发展,现在很多Web应用都采用了前后端分离的架构,前端采用Vue、React等框架,后端采用Spring Boot、Django等框架。而在前端开发中,NPM已经成为了必不可少的工具,但是在Java或Python项目中,如何...
    99+
    2023-07-09
    面试 spring npm
  • Git与Python开发:如何管理项目依赖?
    在Python开发中,依赖管理是至关重要的一环。随着项目的规模增长和开发者的增加,管理依赖变得越来越复杂,这时候Git成为了一个非常有用的工具。本文将介绍如何使用Git来管理Python项目的依赖。 一、什么是依赖管理? 在Python开...
    99+
    2023-06-28
    编程算法 开发技术 git
  • 如何简单的理解依赖注入详解
    依赖注入(Dependency Injection,简称DI)是一种设计模式,用于解耦代码中的依赖关系。简单来说,依赖注入就是将一个...
    99+
    2023-08-14
    依赖注入
  • 如何理解Linux软件包依赖问题
    如何理解Linux软件包依赖问题,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Linux软件包依赖关系让很多使用Linux的人感到很麻烦。在安装Linux系统时,不是选择安装所...
    99+
    2023-06-16
  • 如何理解Angular中的组件通讯和依赖注入
    这篇文章给大家介绍如何理解Angular中的组件通讯和依赖注入,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。 Angular组件间怎么进行通讯?依赖注入是什...
    99+
    2022-10-19
  • 一文讲解如何查看python脚本所依赖三方包及其版本
    在我们有时需要迁移或部署项目时,需要知道项目所依赖的三方包和版本,下面就来一看一看该如何获取吧: 1、首先安装pipreqs库 使用pip命令,利用豆瓣镜像,命令如下: pip in...
    99+
    2023-05-14
    如何查看python模块的依赖包 如何查看python模块的依赖包
  • 如何理解Linux内核及其相关架构的依赖关系
    这篇文章主要介绍“如何理解Linux内核及其相关架构的依赖关系”,在日常操作中,相信很多人在如何理解Linux内核及其相关架构的依赖关系问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理解Linux内核及其...
    99+
    2023-06-12
  • 微服务架构中如何处理服务与服务之间的依赖关系?
    随着互联网的不断发展,业务系统越来越复杂,对于传统的单体应用来说,面临着许多挑战,例如可扩展性不足、部署复杂等等。因此,微服务架构应运而生,它将复杂的业务系统拆分成多个小型服务,每个服务都能够独立地运行和部署。这样可以提高系统的可扩展性和灵...
    99+
    2023-05-17
    微服务架构 依赖关系 服务间通信
  • 如何理解Linux查找后门思路和shell脚本
    本篇内容介绍了“如何理解Linux查找后门思路和shell脚本”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!每个进程都会有一个PID,而每一...
    99+
    2023-06-09
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作