之前的疑惑
其实大概在5个月前学过几天spring,当时对spring依赖 jar导入这部分就非常对迷惑,因为有的教学视频中导入的是spring-core,有的是spring-mvc,选择太多而又不告诉你为什么这么选择 就会给人造成很大的疑惑。
解决疑惑
我们在maven工程中添加下述依赖:(这才是我们学习spring应该导入的maven依赖)
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>LATEST</version> </dependency> </dependencies>
然后看一眼都引用了哪些依赖包:可以看到其实spring-context中也包含了其他的jar包,我们也可以借助maven给我们提供的依赖分析工具进一步查看这几个jar包之间的依赖关系。
这幅图片也清楚的解释了一张很久之前我看不懂的一张图片,如下:
其中的bean、core、Context、EL就对应上面的几个jar包,其中的核心容器(Core Container),指的就是bean工厂用来管理bean对象的那个容器,这个容器的管理需要下面四个jar包的支持
一个简单的IOC实现
我们创建一个maven工程,引入上面的spring maven依赖,然后在resource目录下配置一个bean.xml文件,然后写一个类,比如我写的是AccountService这个类,然后写一个Client类,在里面写入main函数,作为程序启动的入口,在main函数中要写如下的几句代码(至于为什么要写这几句我们接下来会说),然后执行,就可以看到AccountService类中的方法被执行类。
bean.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"> <bean id = "accountService" class="com.lujuan.service.impl.AccountService"> </bean> </beans>
AccountService中的内容
package com.lujuan.service.impl; import com.lujuan.service.IAccountService; public class AccountService implements IAccountService { public void saveAccount() { System.out.println("AccountService: saveAccount"); } }
代码解释说明
在Spring中,我们通过bean.xml文件来进行配置,也就是我们在工厂实现中所用到的properties文件,Spring给我们创建的核心容器是叫做ApplicationContext这样的类,我们在程序启动的时候要获得这样的容器类,然后从这个容器类中获得我们想要的已经被spring通过读取xml配置文件已帮我们实例化的的对象。
ApplicationContext是一个接口,它有很多实现类,其中常用的有三个:
- 基于类路径下的xml配置文件的实现类:ClassPathXmlApplicationContext
- 基于文件系统路径下的xml配置文件实现类:FileSystemXmlApplicationContext
- 基于注解配置类文件的实现类:AnnotationConfigApplicationContext(写config.class进行配置)
我们也通过idea中提供的查找implemention的功能看一下ApplicationContext的实现类:
可以看到它其实还是有比较多的实现类的,可以从不同类型的配置文件中进行配置的解析。
在默认不进行配置的情况下ApplicationContext 初始化的bean对象都是单例模式的,在容器初始化的时候就加载了所有的bean对象。如果想要实现在使用的时候加载初始化bean对象,形成多例模式,那么就需要在xml文件中进行特殊的配置,这部分只是我们在后续的学习中会学习到。
其他知识点
- 在maven中resource目录是一个根目录,对于resource目录下的文件我们可以在代码里面通过文件名称直接访问(虽然不是很清楚为什么maven要这么做,但是事实就是这样的,我们要用于面对事实)
- ApplicationContext该接口有很多父接口,但是我们在程序中常用的容器初始化方式就是ApplicationContext,因为他非常的灵活,他是最子节点的一个接口,因此使用了他。