Spring带你飞(3)—— 有了spring的IOC,我们如何解决程序的耦合问题
IoC的概念
控制反转(Inversion of Control)英文缩写IoC, 即就是把创建对象的权利交给框架,是框架的重要特征。
包括:依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)
作用:降低程序间的耦合关系
IoC前戏(会用)
准备Spring的开发包,本次使用的是spring5.0.2,要求jdk8版本,tomcat版本8.5以上
spring的官网:http://spring.io/
下载地址:https://repo.spring.io/libs-release-local/org/springframework/spring/
下载spring-framework-5.0.2.RELEASE-dist.zip
包,解压后得到三个目录。
Spring的目录结构:
docs:API和开发规范
libs:jar包和源码
scheme:约束
首先看一下我们第一个Spring案例的Demo项目结构
![](https://img2018.cnblogs.com/blog/1415026/201907/1415026-20190725104610209-1755100781.png)
-
创建Maven工程,默认即可,然后在pom.xml里添加下面代码,导入Spring框架的依赖包。
<packaging>jar</packaging> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> </dependencies>
-
在resources文件夹里创建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 http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--把对象的创建交给spring来管理--> <bean id="accountService" class="com.ben.service.impl.AccountServiceImpl"></bean> <bean id="accountDao" class="com.ben.dao.impl.AccountDaoImpl"></bean> </beans>
此时标签bean的属性解释:
id : 获取核心容器对象时的唯一标志;
class: 指定要创建的全限定名。
-
创建业务层接口和实现类
/** * @ClassName: IAccountService * @author: benjamin * @version: 1.0 * @description: 账户业务层接口 * @createTime: 2019/07/21/10:43 */ public interface IAccountService { // 模拟保存账户 void saveAccount(); } /** * @ClassName: 业务层接口实现类 * @author: benjamin * @version: 1.0 * @description: TODO * @createTime: 2019/07/21/10:45 */ public class AccountServiceImpl implements IAccountService { private IAccountDao accountDao; // 此处的依赖关系有待解决 private AccountServiceImpl(){ System.out.println("业务层实现类--创建对象"); } public void saveAccount(){ accountDao.saveAccount(); } }
-
创建持久层接口和实现类
/** * @ClassName: IAccountDao * @author: benjamin * @version: 1.0 * @description: 账户的持久层接口 * @createTime: 2019/07/21/10:43 */ public interface IAccountDao{ //模拟保存账户 void saveAccount(); } /** * @ClassName: AccountDaoImpl * @author: benjamin * @version: 1.0 * @description: 账户的持久层实现类 * @createTime: 2019/07/21/10:44 */ public class AccountDaoImpl implements IAccountDao { public void saveAccount(){ System.out.println("持久层实现类--保存账户"); } }
-
创建一个表现层,用于调用业务层
/** * @ClassName: Client * @author: benjamin * @version: 1.0 * @description: 模拟一个表现层,用于调用业务层 * @createTime: 2019/07/21/10:43 */ public class Client { // 获取Spring的IoC核心容器,并根据id获取对象 public static void main(String[] args) { //1. 获取核心容器对象 ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); // ApplicationContext ac = new FileSystemXmlApplicationContext("C:\\Users\\zhy\\Desktop\\bean.xml"); //2.根据id获取Bean对象 // 两种方式: IAccountService as = (IAccountService) ac.getBean("accountService"); IAccountDao adao = ac.getBean("accountDao", IAccountDao.class); System.out.println(as); System.out.println(adao); // as.saveAccount(); } }
运行结果:
Spring的工厂类
ApplicationContext接口的3个实现类
- ClassPathXmlApplicationContext:它可以加载类路径下的配置文件,要求配置文件必须在类路径下。不在的话,加载不了。(更常用)
- FileSystemXmlApplicationContext:它可以加载磁盘任意路径下的配置文件(必须有访问权限)
- AnnotationConfigApplicationContext:它是用于读取注解创建容器的
举例:
public static void main(String[] args) {
//1. 获取核心容器对象,两种方式,推荐第一种
// ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
ApplicationContext ac = new FileSystemXmlApplicationContext("C:\\Users\\benjie\\Desktop\\bean.xml");
//2.根据id获取Bean对象
// 两种方式:
IAccountService as = (IAccountService) ac.getBean("accountService");
IAccountDao adao = ac.getBean("accountDao", IAccountDao.class);
System.out.println(as);
System.out.println(adao);
}
ApplicationContext和BeanFactory的区别
ApplicationContext:单例对象适用,采用此接口
它在构建核心容器时,创建对象采取的策略是采用立即加载的方式。也就是说,只要一读取完配置文件马上就创建配置文件中配置的对象。
BeanFactory:多例对象使用
它在构建核心容器时,创建对象采取的策略是采用延迟加载的方式。也就是说,什么时候根据id获取对象了,什么时候才真正的创建对象。
下面我们来用IDEA进行代码调试,
首先我们在程序第27行处打一个断点,点击debug运行。
结果:
BeanFactory演示,代码如下:
public static void main(String[] args) {
//-----BeanFactory----
Resource resource = new ClassPathResource("bean.xml");
BeanFactory factory = new XmlBeanFactory(resource);
IAccountService as = (IAccountService)factory.getBean("accountService");
System.out.println(as);
}
发现,只有在使用的时候(打印as)才会创建对象.