一、IOC控制反转和DI依赖注入

  1.控制反转,字面可以理解为:主动权的转移,原来一个应用程序内的对象是类通过new去主动创建并实例化的,对对像创建的主动权在程序代码中。程序不仅要管理业务逻辑也要管理对的象创建和依赖关系。这是很累的,也跟软件工程 "低耦合高内聚" 的概念不十分符合。

  

  有了spring的ioc容器之后,对象的实例化和依赖关系管理都由IOC容器进行统一管理,主体类只要依赖ioc容器就够了,需要啥,容器会给他注入进去,也就是只要声明对象不用再主动去new,ioc容器帮忙把相应的对象注入到声明对象中,使其变成实例化对象。(类似主体类提供一个躯体,ioc容器把灵魂注入进去,使其变成一个生命体,激活他),这样创建对象的主动权就转移交接了,

  

二、使用xml配置方式实现IOC

  1.在ioc容器中配置了dao实现类和service类的bean,在容器加载的时候就会实例化这些bean到内存中。(bean.xml配置如下)

 <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
"> <!-- BookDao Bean -->
<bean id="bookDao" class="com.study.DaoImpl.BookDaoImpl"></bean> <!-- BookService Bean-->
<bean id="bookService" class="com.study.Service.BookService">
<!-- BookService中的声明了BookDao对象,通过ref属性将BookDao的bean注入到对象中 -->
<property name="bookDao" ref="bookDao"/>
</bean>
</beans>

  2. service类中需要用到dao类的实例(正常情况下需要new一个dao类对象),但是用ioc容器接管后只需要声明dao接口对象即可,然后写一个dao对象的set方法。(要注入的对象必须要有set方法,否则将报错 Bean property 'bookDao' is not writable or has an invalid setter method)因为spring注入是根据反射机制实现的,他在反射注入的时候会调用该方法名的set方法,如果set方法写错,或者根本没写,那么注入就会失败。(BookService类如下)

 public class BookService {
private BookDao bookDao; public BookService() {
System.out.println("BookService实例化");
} public void setBookDao(BookDao bookDao) {
System.out.println("BookService属性初始化装配成功");
this.bookDao = bookDao;
} public void storeBook(String bookname){
System.out.println("图书上架");
System.out.println(bookDao.addBook(bookname));
}
}

  如上代码:BookSerivce类需要用到BookDao对象,但是却没有new对象,只有一个set方法,这个set方法就是ioc容器注入的入口(必不可少),

  3.此处我们用ApplicationContext作为容器,初始化配置文件,然后从容器中根据id名取出容器中已经帮我们实例化好的对象。

 public class TestDmeo {
BookService bookService; @Test
public void testStoreBook(){
System.out.println("容器初始化");
ApplicationContext app = new ClassPathXmlApplicationContext("bean.xml");
bookService = (BookService) app.getBean("bookService");//将对象注入到声明好的BookService对象中。(bookService就是配置文件中的id)
bookService.storeBook("Spring MVC");
}
}

  getBean中的参数就是配置文件中的bean的id名,这个id在spring进行反射实例化的时候,相当于实例化对象的名称:

   

   4.dao类和实现类如下:

接口类:

 public interface BookDao {
public String addBook(String BookName);
}

实现类:

 public class BookDaoImpl implements BookDao {

     public BookDaoImpl() {
System.out.println("BookDao实例化");
} public String addBook(String BookName) {
return BookName+"添加成功";
}
}

  5.运行测试结果:

  

 6.大体思路如下图:

  程序中除了初始化容器用了new对象,其余的基本没有new的存在。

二、注解方式配置IOC

  注解配置方式目的和xml配置的目的一样,都是为了实现bean的创建。常用的注解如下:

      • @Component 在类定义之前添加@Component注解,他会被spring容器识别,并转为bean。
      • @Repository 对Dao实现类进行注解 (特殊的@Component)
      • @Service 用于对业务逻辑层进行注解, (特殊的@Component)
      • @Controller 用于控制层注解 , (特殊的@Component)

  

  装配注解如下:

      • @Autowired 默认按照类型装配注入,想按照名称来装配的话要结合@Qualifier(“name”)一起使用,使用@Autowired注解可以不用set方法。@Autowired 注释进行自动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个
      • @Qualifier("name") 中的name是bean的名字,也就是id,和@Autowired可以作为限定专配对象的名称
      • @Resource 默认按照名称装配注入,当找不到对应名成的bean的时候就按照类型匹配,如果还是找不到的话就会报错,@Autowired是spring提供的,@Resource是javaee提供,使用@Resource可以减少对spring的依赖

  范例:

  1.例子同上,只是配置bean的方式从xml文件中转移到了代码中,用注解体现。

  

  2.除了把配置文件中<bean id="" class=""/>变成对应的注解外,另外一个区别在于,bean.xml文件中的修改,需要做如下,配置才能够使注解生效

  

  context的配置有如下方法:

  1.仅扫描特定包下的特定类

 <context:component-scan base-package="com.study" resource-pattern="Service/B*.class"/>

  这是扫描Service包下B开头的所有类。

  2.使用<context:include-filter .../>和<context:exclude-filter .../>配置那些需要和不需要的扫描的包

过滤器类型 描述
annotation 过滤器扫描使用注解所标注的那些类,通过expression属性指定要扫描的注释
assignable 过滤器扫描派生于expression属性所指定类型的那些类
aspectj 过滤器扫描与expression属性所指定的AspectJ表达式所匹配的那些类
custom 使用自定义的org.springframework.core.type.TypeFliter实现类,该类由expression属性指定
regex 过滤器扫描类的名称与expression属性所指定正则表示式所匹配的那些类
 <!-- 容器扫描包下的注解配置组件 -->
<context:component-scan base-package="com.study" use-default-filters="false"><!--- user-default-filters="false"必须要设置成false,不然下面配置的过滤规则会被默认的注解过滤方式覆盖 ——>
<context:include-filter type="aspectj" expression="com.study.Service.*"/> <!-- 过滤器扫描与expression属性所指定的AspectJ表达式所匹配的那些类 -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/><!-- 过滤指定的注解 -->
<context:include-filter type="assignable" expression="com.study.Service.BookService"/><!-- 过滤指定的类或接口,路径要完整,如果是接口的话,所有派生类都会被过滤 -->
<context:include-filter type="regex" expression="com.*"/><!-- 过滤器扫描类的名称与expression属性所指定正则表示式所匹配的那些类 -->
</context:component-scan>

  <context:exclude-filter ../>要配在<context:include-filter .../>的后面。

  配置了<context:include-filter .../>,他会把符合过滤条件的类转化成bean,并不是只有@Component、@Service。。。等注解才能注解bean,通过过滤器也可以达到转换成bean的效果。

  最后:aspectj表达式可参考:http://blog.csdn.net/peng658890/article/details/7223046

Spring对IOC的理解的更多相关文章

  1. Spring中IOC的理解

    Spring中IOC的理解 1.什么是IOC? (1)控制反转.把对象创建和对象间的调用过程交给Spring进行管理. (2)使用IOC的目的:为了耦合度降低. 2.IOC底层原理? (1)xml解析 ...

  2. 浅析对spring中IOC的理解

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  3. 谈谈对Spring IOC的理解(转)

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  4. 谈谈对Spring IOC的理解

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  5. Spring系列之谈谈对Spring IOC的理解

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IOC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  6. 谈谈对Spring IOC的理解【转】

    学习过Spring框架的人 一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大 ...

  7. spring ioc DI 理解

    下面是我从网上找来的一些大牛对spring ioc和DI的理解,希望也能让你对Spring ioc和DI的设计思想有更进一步的认识. 一.分享Iteye的开涛对Ioc的精彩讲解 Ioc—Inversi ...

  8. Spring IOC的理解

            学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理 ...

  9. 谈谈对Spring IOC的理解(转载)

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

随机推荐

  1. ps通道抠章

    1. 打开图片 2. 使用椭圆形选框工具,选择章所在范围(ALT+SHITF+鼠标左键) 3.复制图层(CTRL+J)为图层1,隐藏背景 4.进入通道,选择对比度最大的通道,复制通道副本 5.反选(C ...

  2. 【动画】JQuery实现冒泡排序算法动画演示

    1 前言 冒泡排序是大家最熟悉的算法,也是最简单的排序算法,因其排序过程很象气泡逐渐向上漂浮而得名.为了更好的理解其基本的思想,毛三胖利用JQuery实现了冒泡排序的动画演示,并计划陆续实现其它排序算 ...

  3. 撸一撸Spring Cloud Ribbon的原理-负载均衡器

    在上一篇<撸一撸Spring Cloud Ribbon的原理>中整理发现,RestTemplate内部调用负载均衡拦截器,拦截器内最终是调用了负载均衡器来选择服务实例. 接下来撸一撸负载均 ...

  4. Android Native App自动化测试实战讲解(上)(基于python)

    1.Native App自动化测试及Appuim框架介绍 android平台提供了一个基于java语言的测试框架uiautomator,它一个测试的Java库,包含了创建UI测试的各种API和执行自动 ...

  5. Java经典编程题50道之四十

    将几个字符串排序(按英文字母的顺序). public class Example40 {    public static void main(String[] args) {        Stri ...

  6. C#委托与事件--后续补充

    委托.事件补充 针对昨天文章 委托:让方法可以跟简单对象一样作为参数进行传递,也就是将方法作为参数进行封装. 方法:本质就是代码段 其实也好理解,目的就是为了封装,多态,既然简单对象如int i可以做 ...

  7. 使用canvas编写时间轴插件

    使用canvas编写时间轴插件 背景 项目中有一个视频广场的功能,需要一个时间轴类似视频播放中进度条功能一样显示录像情况,并且可以点击.拖动.放大缩小展示时间轴,获取到时间轴的某个时间.原来的时间轴是 ...

  8. 3道acm简单题(2011):1.判断是否能组成三角形;2.判断打鱼还是晒网;3.判断丑数。

    //1.输入三个正整数A.B.C,判断这三个数能不能构成一个三角形.//思路:最小的两边之和是否是大于第三边#include<iostream>#include<algorithm& ...

  9. Qt msvc Modules

    3D ActiveQt container ActiveQt server Bluetooth Concurrent Core Enginio Declarative Gui Help Locatio ...

  10. 情景linux--如何摆脱深路径的频繁切换烦恼?

    情景 通常情况下,在linux系统上切换目录的成本很低,使用cd命令就可以了.如果需要在一个目录的不同的子目录和其父目录之间切换,进入到这个目录之后,再使用相对路径会比较方便.如果要切换的目录的路径较 ...