ioc简介:

什么是IOC呢?

IOC(Inversion of Control),中文意思就是控制反转,ioc并不是一种特定的编程语言,指的是一种编程思想,指的是将创建对象的操作权限交给容器(这里指的是spring容器),通过容器来创建对象和管理对象,简单来说就是将原先的控制权由程序本身转给容器(本篇主要指的是spring)

依赖注入

依赖注入(Dependency Injection):依赖注入指的是在程序的运行过程中,当程序需要调用另一个对象协助时,不用在代码中创建对象并进行调用,而是将创建过程与调用过程交给外部的容器来管理(spring),由外部容器创建后传递给层序

为什么会有依赖注入的存在?

一个稍微复杂一点的程序,其组成的类基本都是两个或两个以上了,这些类组成应用程序完成相关的业务逻辑。每个对象负责管理与自己相互协作的对象的引用,一个对象可能会引用多个对象,这就会导致高度的耦合和代码的难以测试,编码的基本准则是“低耦合,高内聚”

耦合具有两面性:

1:紧密的耦合会导致代码难以测试,难以复用,难以理解

2:一个程序要想完成特定的功能,一定程度的耦合又是必须的,不同的类之间必须进行一定的交互

依赖注入:通过依赖注入,对象的依赖关系将由负责协调系统中各个对象的第三方组件在创建对象时设定,对象无需自行创建或管理它们之间的依赖关系,也就是依赖关系将被注入到它们的依赖关系中去

实现依赖注入的两种方式

# 基于xml配置文件的依赖注入

setter方法

以下的例子相当于在一个类中使用另一个类中的方法

1:创建一个UserDao接口

package com.doaoao.dao;
public interface UserDao {void addUser();
}

2:创建UserDao接口的实现类

package com.doaoao.impl;
import com.doaoao.dao.UserDao;
public class UserDaoImpl implements UserDao {@Overridepublic void addUser() {System.out.println("添加用户");}
}

3:创建UserService接口

package com.doaoao.dao;
public interface UserService {void addUser();
}

4:创建UserService的实现类(在Service中使用UserDao)

package com.doaoao.impl;import com.doaoao.dao.UserDao;
import com.doaoao.dao.UserService;public class UserServiceImpl implements UserService {private UserDao userDao;@Overridepublic void addUser() {// 注:之前如果想使用UserDao的对象时,必须先创建该对象,如下
        // UserDao userDao = new UserDaoImpl()// 使用spring 由spring为我们创建对象userDao.addUser();  // 调用UserDaoImpl中的实现方法
    }

  // 要给UserDao添加getter和setter方法public UserDao getUserDao() {return userDao;}// spring容器在实现依赖注入时会调用set方法,将userDao对象注入给当前对象,也就是UserServiceImpl类的对象  public void setUserDao(UserDao userDao) { this.userDao = userDao; } }

5:修改配置文件中的内容(当Spring读取配置文件时,会将userDao注入到对应的类中)

<bean id="userService" class="com.doaoao.impl.UserServiceImpl"><property name="userDao" ref="userDaoId" />     <!-- ref的值为下方bean的id值 userDao与 private UserDao userDao中的userDao命名得一致--> </bean> <bean id="userDaoId" class="com.doaoao.impl.UserDaoImpl" />

6:添加测试类

    @Testpublic void Test02(){// 读取spring配置文件ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// 从配置文件中获取对应id所对应的对象UserService userService = (UserService) context.getBean("userService");userService.addUser();}

# 使用spring的依赖注入之后,spring容器会帮我们创建UserDaoImpl的对象,并通过setter方法注入到UserService中的userDao属性上面

## 构造注入(容器通过构造方法将实例化的对象进行注入)

1:修改之前的UserServiceImpl,添加有参构造方法

package com.doaoao.impl;
import com.doaoao.dao.UserDao;
import com.doaoao.dao.UserService;
public class UserServiceImpl implements UserService {private UserDao userDao;@Overridepublic void addUser() {// 注:之前如果想使用UserDao的对象时,必须先创建该对象,如下
        // UserDao userDao = new UserDaoImpl()// 使用spring 由spring为我们创建对象userDao.addUser();  // 调用UserDaoImpl中的实现方法
    }// 构造注入public UserServiceImpl(UserDao userDao) {this.userDao = userDao;}
}

2:修改配置文件

<bean id="userService" class="com.doaoao.impl.UserServiceImpl"><constructor-arg name="userDao" ref="userDaoId" />
</bean>
<bean id="userDaoId" class="com.doaoao.impl.UserDaoImpl" /><!-- userDao要与构造方法中的参数一致 UserDao userDaouserDaoId与下方的bean id要一致 -->


## 基于注解的依赖注入

  @Controller -----> springmvc中的controller

  @Repository ----> dao层

  @Service ---------> service层

  @Component --->可以代替上方三个

使用依赖注入,我们九不必再applicationContext.xml中注册bean

1:在配置文件中添加文件扫描器(使用注解就得先加上文件扫描器,扫描对应的类)

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!-- 注册文件扫描器 --><context:component-scan base-package="com.doaoao" />
</beans>

2:在类上使用注解 @Component,该注解中的参数用于指定该类的id

package com.doaoao.impl;
import com.doaoao.dao.UserDao;
import org.springframework.stereotype.Repository;
@Component("userDao")
public class UserDaoImpl implements UserDao {@Overridepublic void addUser() {System.out.println("执行了addUser");}
}

在spring中提供类与@Component等效的注解

  @Repository 用于对 DAO 实现类进行注解
  @Service 用于对 Service 实现类进行注解
  @Controller 用于对 Controller 实现类进行注解

例如在dao层的 UserDaoImpl 中使用 @Repository 注解

package com.doaoao.impl;
import com.doaoao.dao.UserDao;
import org.springframework.stereotype.Repository;
@Repository("userDao")
public class UserDaoImpl implements UserDao {@Overridepublic void addUser() {System.out.println("执行了addUser");}
}

3:在service层的 UserServiceImpl 上使用 @Service

package com.doaoao.impl;
import com.doaoao.dao.UserDao;
import com.doaoao.dao.UserService;
import org.springframework.stereotype.Service;
@Service("userService")
public class UserServiceImpl implements UserService {private UserDao userDao;@Overridepublic void addUser() {// 使用spring 由spring为我们创建对象userDao.addUser();
    }// 构造注入public UserServiceImpl(UserDao userDao) {this.userDao = userDao;}
}

4:创建测试方法(与之前相同)

    @Testpublic void Test02(){// 读取spring配置文件ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// 从配置文件中获取对应id所对应的对象UserService userService = (UserService) context.getBean("userService");userService.addUser();}

@Autowrite注解

加上该注解后,会按照类型进行装配,上面的示例中通过UserServiceImpl的构造方法对UserDao的注入,我们可以将这个构造方法省略,我们可以在private UserDao userDao上添加@Autowired注解,该注解默认使用按类型自动装配,即容器会查找UserDao类型的实例将其注入,spring容器会自动查找该对象

当使用@AUtowrite注解时,@Repository("userDao") 可以改写成 @Repository,因为默认是根据类型进行注入的,会自动找到该类型所对应的对象

我么可以对其进行修改,让其根据名称进行注入,还可以使用 @Qualifier注解让@Autowrite根据名称自动装配,

@Qualifier中的名称要跟UserDaoImpl类中@Repository("userDao")的名称一致,spring在查找对象时就会根据 userDao这个名字去查找

package com.doaoao.impl;import com.doaoao.dao.UserDao;
import com.doaoao.dao.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;@Service("userService")
public class UserServiceImpl implements UserService {    @Autowired@Qualifier("userDao")private UserDao userDao;@Overridepublic void addUser() {userDao.addUser(); }// 无需构造方法
    // public UserServiceImpl(UserDao userDao) {
    //     this.userDao = userDao;
    // }
}

@Resource注解(该注解不是spring提供的,是java提供的注解)

该注解默认使用名字进行注解(来完成装配的/注入的)当我们下方没有写名字时,就是使用类型进行装配的(和 @Autowired)

可以按照名字进行装配 @Resource(name = “userDao”),当指定名字时,名字得和@Repository("userDao") 一样

@Service("userService")
public class UserServiceImpl implements UserService {@Resourceprivate UserDao userDao;@Overridepublic void addUser() {userDao.addUser();}
}

下面另一种写法利用类型进行bean的注入

@Service("userService")
public class UserServiceImpl implements UserService {@Resource(type = "userDao")private UserDao userDao;@Overridepublic void addUser() {userDao.addUser();}
}

两个区别:@Autowired是spring提供的,@Resource是java提供的,这两种注解在实际开发中二选一即可

@Autowired默认根据类型进行装配,@Resource默认使用名字进行装配

// 使用注解实现初始化和销毁操作

@PostConstruct
public void before() {System.out.println("开始");
}@PreDestroy
public void after() {System.out.println("结束");
}

利用注解@Scope指定bean的作用域,默认的作用域为 singleton 单例模式

@Scope("prototype")
@Repository("userDao")
public class UserDaoImpl implements UserDao {@Overridepublic void addUser() {System.out.println("执行了方法 UserDaoImpl");}
}

## 注解和xml配置的利弊

注解的好处是,配置方便,直观。但其弊端也显而易见:以硬编码的方式写入到了 Java代码中,其修改是需要重新编译代码的。

XML 配置方式的最大好处是,对其所做修改,无需编译代码,只需重启服务器即可将新的配置加载。

若注解与 XML 同用,XML 的优先级要高于注解。这样做的好处是,需要对某个 Bean 做修改,只需修改配置文件即可。当然,此时,Bean 类要有 setter 或构造器。

## 如何添加多个配置文件

随着系统中的Bean的数量增加,会导致配置温江变得及其的臃肿,会导致可维护性的降低,为了避免这种事情的发生,可以将Spring配置文件分解成多个配置文件

# 添加多个配置文件-方式1

// 在resource目录下创建多个配置文件
spring-app.xml
spring-bean.xml// 在测试方法中:将配置文件的文件名写道数组中,然后将该数组作为参数传入 ClassPathXmlApplicationContex
String[] files = {"spring-aop.xml","spring-bean.xml","applicationContext.xml"};
ApplicationContext context = new ClassPathXmlApplicationContext(files);

# 添加多个配置文件-方式2

选取一个主配置文件,例如选取 applicationContext.xml

在applicationContext.xml配置文件中加入如下的内容,这时就好比将 applicationContext.xml 配置文件变成一个父配置文件

<import resource="spring-aop.xml"/>
<import resource="spring-bean.xml"/><!-- 另一种写法,使用通配符的方式 --><!-- 当用通配符的方式写的时候,主配置文件不以 "spring作为开头" --><import rescorce="spring-*.xml">

然后再测试代码中使用即可

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

...

本笔记参考自:小猴子老师教程 http://www.monkey1024.com

转载于:https://www.cnblogs.com/Doaoao/p/10740366.html

spring_ioc,DI相关推荐

  1. python ioc di_Spring介绍,IOC(控制反转),DI(依赖注入)介绍及两种注入方法

    Spring介绍,IOC(控制反转),DI(依赖注入)介绍及两种注入方法 第一中方法:在xml文件中注入: (1)开源的轻量级的应用开发框架 特点:a.简化开发:b.解耦:c.集成: 原理对象与对象之 ...

  2. DIP(依赖倒置原则),IoC(控制反转),DI(依赖注入)复习总结

    原文地址:http://blog.csdn.net/qqlinke/archive/2011/04/05/6303689.aspx ---- 概念 ---- ◆1.依赖倒置原则(DIP,Depende ...

  3. si,di,ds,es寄存器

    ds和es是段寄存器,si和di是变址寄存器 ds和si组成:ds:si es和di组成:es:di 常用把地址的值赋值给另地址. ds:si ==>es:di 这里还应用到cx,表示赋值的长度 ...

  4. SSM—Spring框架,IOC理论推导,Hello Spring,IOC创建对象方式,Spring的配置,DI(依赖注入)

    文章目录 1.Spring 1.1.Spring简介(了解) 1.2.spring优点 1.3.组成(七大模块) 1.4.拓展 2.IOC理论推导 2.1.IOC本质 3.Hello Spring 4 ...

  5. Spring源码学习笔记:Spring设计模式对比和Spring的OOB,BOP,AOP,IOC,DI/DL

    1.博客内容均出自于咕泡学院架构师第三期 2.架构师系列内容:架构师学习笔记(持续更新) 1.GOF 23总设计模式归纳 分类 设计模式 创建型 工厂方法模式(Factory Method).抽象工厂 ...

  6. 谈谈php里的IOC控制反转,DI依赖注入

    理论 发现问题 在深入细节之前,需要确保我们理解"IOC控制反转"和"DI依赖注入"是什么,能够解决什么问题,这些在维基百科中有非常清晰的说明. 控制反转(In ...

  7. et200sp系统服务器模块,ET200SP选型,DI模块之间的区别-工业支持中心-西门子中国...

    DI 8*24VDC ST    DC标准型  漏型输入 DI 8*24VDC BA    DC基本型  漏型输入 DI 8*24VDC SRC BA  DC基本型  源型输入 DI 4*120``` ...

  8. Spring——如何理解Spring,DI和IoC

    文章目录 1. Spring 是什么 2. 什么是容器 3. 什么是 IoC 对比总结规律 4. Spring IoC 容器的最核心功能 5. DI概念说明 1. Spring 是什么 用一句话概括: ...

  9. Spring基本概念:IoC,DI,Wiring

    文章目录 一.IoC(控制反转) 二.DI(依赖注入) 三.Bean configuration(配置) 1. XML Schema-based configuration:基于XML模式的配置 2. ...

最新文章

  1. CADisplayLink 及定时器的使用
  2. Kubernetes — 在 OpenStack 上使用 kubeadm 部署高可用集群
  3. mahout in Action2.2-给用户推荐图书(2)-分析对用户推荐书目的结果
  4. 南农计算机考研985,江浙沪985/211考研难度梯队排名
  5. 向量叉乘判断两向量之间是顺时针还是逆时针
  6. C++有名管道通信简单示例
  7. Chrome浏览器提示您的连接不是私密连接解决办法
  8. 【无广告】一位算法工程师从30+场秋招面试中总结出的超强面经——目标检测篇...
  9. pyinstaller编译出的exe被杀毒软件认为是木马
  10. java.lang.ClassCastException: Ljava.lang.Object; cannot be cast to com.entity.Advertisem异常
  11. 物联网安全架构与基础设施
  12. ubuntu 8.04下安装yEd
  13. 使用Audacity软件对清浊音进行时频分析并描述其特点
  14. 计算机四级网络工程师 郑州报考条件,郑州一建报考条件2021年
  15. EAM系统对企业的价值
  16. MySql的相关资操作
  17. ArcView GIS 应用与开发技术(4)-地图投影
  18. Java基础入门第二章答案
  19. 百度搜索排行最新算法
  20. Windows下 文件夹加密

热门文章

  1. HDU 1175 连连看
  2. static_cast, dynamic_cast, reinterpret_cast, const_cast区别比较
  3. Spring学习(三)Spring AOP 简介
  4. Struts第一个案例搭建
  5. python中with语句的使用
  6. 算法复习——虚树(消耗战bzoj2286)
  7. 【BZOJ 2298】 2298: [HAOI2011]problem a (DP)
  8. ThinkPHP集成万象优图
  9. java.lang.OutOfMemoryError: Java heap space错误及处理办法(收集整理、转)
  10. 英文简历的几种常见形式