一、Spring 的定义和核心功能
定义: Spring 是包含了众多工具方法的 loC 容器
核心功能:
- 将对象
存 入到 Spring 容器中 - 从 Spring 容器中获
取 对象
1.1 loC 容器
容器 的定义我们都知道,就是用来容纳某些物品的装置
那么 IoC 又是什么呢?
IoC (Inversion of Control) 即“控制反转” ,总结下来就是 Spring 是一个 “控制反转” 的容器
众所周知,Java 是面向对象的,面对一个比较复杂的系统,我们会将该系统分解成一个一个对象,这些对象类通过封装,内部进行实现功能,对外部是透明的,可以灵活的被重用,被扩展,从而使得问题的解决变得容易。
IoC 理论就是借助于第三方实现具有依赖关系的对象之间的解耦
比如 A、B 这两个对象之间有着相互依赖的关系,A依赖于B。
- 如果没有 IoC 容器的话,在实现 A 对象的时候,当需要 B 对象时,就会主动创建出一个 B 对象(new B())或者使用已经创建出来的 B 对象,但无论是哪种情况,A 对象掌握了绝对的主动权
- 如果引入 IoC 容器的话,当实现 A 对象的过程中需要 B 对象时,IoC 容器会主动创建出一个 B 对象,注入到 A 对象中,A 直接拿取现成的 B 对象就行,此时对象 A 就变成了被动方,控制权颠倒,也就是 “控制反转”了
可以看的出来,当引入了 IoC 容器后,A 对象根本无需再考虑 B对象了,两者之间没有了耦合关系 ,对象 A 只管自己实现自己的功能,想要用 B 对象,直接薅注入进来的对象 B 直接用即可,用完以后就将其放回 IoC 容器中。而 new 对象 B 的方法,就相当于想要什么,现场做一个,用完就甩了,下回还想要,就再现场做一个
1.2 DI
在上面讲到 IoC 容器时有提到一个词,叫“注入”
DI (Dependency Injection)即“依赖注入”
从宏观来讲,DI 和 IoC 意思是差不多的,但是细细品来又有所不同,两者实际上上是从两个不同的角度说明同一件事情。
思考,既然 IoC 是控制反转,那么究竟是什么东西被反转了呢?
根据上面讲述 IoC 的小节,不难知道,获取依赖对象的过程被反转 了。被反转后,获取依赖对象的过程从自己创建管理变成了 IoC 容器直接将依赖对象注入,拿现成的。因此“控制反转”又有了新的名字 “依赖注入”,所谓 “依赖注入”,就是由 IoC 容器在运行期间,动态地将某种依赖关系注入到对象中 。
IoC 是一种思想 ,是一种指导原则
DI 就是将思想进行实现的具体方法
通过引入了 IoC 容器这样的一个思想,具体用依赖注入(DI)的方式,实现对象之间的解耦
比如 我想将我的电脑进行连上网络(思想),那究竟是连校园网呢,还是直接手机热点分享呢,这就是具体实现。
二、Spring 的创建和使用
2.1 创建一个 Spring 项目
步骤一:创建一个普通的 Maven 项目
File -> New -> Project
Maven -> Next
填写项目名称 和项目存储路径
步骤二:添加 Spring 依赖
在 pom.xml 中添加 Spring 框架的支持(这是一段固定的代码,直接粘贴复制即可)
<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>
添加完依赖后,需要点击右上角的 Maven ,点击刷新 按钮,进行刷新操作
引入的依赖包括 spring -content ,即 Spring 的上下文 ,通过这个来获取 Spring 容器。还有 spring-beans ,bean 指的就是对象,该依赖就是管理对象的模块
步骤三:添加一个启动类
在 java 文件夹下创建一个启动类,启动类就是一个包含 main 方法的类
2.2 存储 Bean 对象
Bean 指的就是 Java中的对象
步骤一:创建一个简单的 Bean 对象
步骤二:将创建好的 Bean 对象注册到 Spring 容器中
在 resource 下添加配置文件 spring.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 http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
然后,正式将之前创建的 Bean 对象(BeanDemo)注册到 Spring 中
<beans>
<bean id="beanOne" class="com.beans.BeanDemo"></bean>
</beans>
回头获取 BeanDemo 对象就可以通过 beanOne 这个id,class 中写的是 BeanDemo 对象所在的包名加类名
2.3 获取并使用 Bean 对象
步骤一:得到 Spring 上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
创建的时候传入的参数要和之前的配置文件名对应
步骤二:获取某一个指定的 Bean 对象
BeanDemo beanDemo = (BeanDemo) context.getBean("beanOne");
步骤三:使用 Bean 对象
beanDemo.func();
2.4 程序结果
至此,一个简单的 Spring 的创建和使用代码就完成了,只需要点击 main 方法中的绿色小三角即可运行
2.5 补充
2.5.1 ApplicationContext 和 BeanFactory 的区别
获取上下文对象除了使用 ApplicationContext 外也可以使用 BeanFactory
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring.xml"));
通过 beanfactory 变量也可以 getBean() ,用法和 ApplicationContext 类似,所得效果一样
两者区别:
- 从
继承关系 来说,ApplicationContext 属于 BeanFactory 的子类 - 从
功能方面 来说,BeanFactory 提供了基础的访问容器的能力,作为其子类,ApplicationContext 除了继承了 BeanFactory 的所有功能外,该类还添加了国际化支持、资源访问支持以及事件传播等方面的支持 - 从
性能方面 来说,ApplicationContext 一次性加载并初始化完所有的 Bean 对象(初始化慢,调用快),而 BeanFactory 是需要哪个 Bean 才会加载哪个,更加的轻量(初始化快,调用慢)
2.5.2 getBean 方法的更多用法
上面举例的 getBean 方法的用法是直接传入需要用的 Bean 的 id ,但是缺点 是需要进行类型强制转换
还有两种常见的用法
传入需要的 Bean 的类对象:
BeanDemo beanDemo = context.getBean(BeanDemo.class);
优点是根据类型获取 Bean 对象,不需要进行类型强转
缺点 就是当 BeanDemo 类被重复注册 到 spring.xml 中时,就会程序异常
传入需要的 Bean 的 id 和类型:
BeanDemo beanDemo = context.getBean("beanOne",BeanDemo.class);
该方法使用的频率更加的高,id 和 类型的传入,就可既不用类型强转,也避免了类型多次注册导致的异常
2.6 小结
完!
|