新闻中心

工厂ioc是什么意思

工厂ioc是什么意思

IOC的实现原理—反射与工厂模式_Hopefully Sky的博客-CSDN博客_ioc工厂模式

扫一扫,分享内容

打赏作者

GeorgiaStar

你的鼓励将是我创作的最大动力

您的余额不足,请更换扫码支付或

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。

2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

一步一步造个IoC轮子(一):IoC是什么 - BlackMagic# - 博客园

 

 

 

 

Copyright © 2022 BlackMagic#

Ioc模式与工厂模式比较

Ioc模式与工厂模式比较

2010-03-26 来源:网络

分离关注( Separation of Concerns : SOC)是Ioc模式和AOP产生最原始动力,通过功能分解可得到关注点,这些关注可以是 组件Components, 方面Aspects或服务Services。

从GoF设计模式中,我们已经习惯一种思维编程方式:Interface Driven Design 接口驱动,接口驱动有很多好处,可以提供不同灵活的子类实现,增加代码稳定和健壮性等等,但是接口一定是需要实现的,也就是如下语句迟早要执行:

AInterface a = new AInterfaceImp();

AInterfaceImp是接口AInterface的一个子类,Ioc模式可以延缓接口的实现,根据需要实现,有个比喻:接口如同空的模型套,在必要时,需要向模型套注射石膏,这样才能成为一个模型实体,因此,我们将人为控制接口的实现成为“注射”。

Ioc英文为 Inversion of Control,即反转模式,这里有著名的好莱坞理论:你呆着别动,到时我会找你。后被Martin Fowler改名为 Dependency Injection 依赖注射,也就是将类之间的关系通过第三方进行注射,不需要类自己去解决调用关系。

其实Ioc模式也是解决调用者和被调用者之间的一种关系,上述AInterface实现语句表明当前是在调用被调用者AInterfaceImp,由于被调用者名称写入了调用者的代码中,这产生了一个接口实现的原罪:彼此联系,调用者和被调用者有紧密联系,在UML中是用依赖 Dependency 表示。

但是这种依赖在分离关注的思维下是不可忍耐的,必须切割,实现调用者和被调用者解耦,新的Ioc模式 Dependency Injection 模式由此产生了, Dependency Injection模式是依赖注射的意思,也就是将依赖先剥离,然后在适当时候再注射进入。

Ioc模式(Dependency Injection模式)有三种:

有过EJB开发经验的人都知道,每个EJB的调用都需要通过JNDI寻找到工厂性质的Home接口,在我的教程

章节中,我也是从依赖和工厂模式角度来阐述EJB的使用。

在通常传统情况下,为了实现调用者和被调用者解耦,分离,一般是通过工厂模式实现的,下面将通过比较工厂模式和Ioc模式不同,加深理解Ioc模式。

假设有两个类B 和 C:B作为调用者,C是被调用者,在B代码中存在对C的调用:

实现comp实例有两种途径:单态工厂模式和Ioc。

工厂模式实现如下:

  public B(){

    this.comp = myFactory.createInstanceOfC();

  }

   public void someMethod(){

    this.comp.sayHello();

  }

  ......

}

特点:

使用Ioc依赖性注射( Dependency Injection )实现Picocontainer如下,B类如同通常POJO类,如下:

假设C接口/类有有一个具体实现CImp类。当客户端调用B时,使用下列代码:

因此,当客户端调用B时,分别使用工厂模式和Ioc有不同的特点和区别:

主要区别体现在B类的代码,如果使用Ioc,在B类代码中将不需要嵌入任何工厂模式等的代码,因为这些工厂模式其实还是与C有些间接的联系,这样,使用Ioc彻底解耦了B和C之间的联系。

使用Ioc带来的代价是:需要在客户端或其它某处进行B和C之间联系的组装。

所以,Ioc并没有消除B和C之间这样的联系,只是转移了这种联系。

这种联系转移实际也是一种分离关注,它的影响巨大,它提供了AOP实现的可能。

AOP我们已经知道是一种面向切面的编程方式,由于Ioc解放自由了B类,而且可以向B类实现注射C类具体实现,如果把B类想像成运行时的横向动作,无疑注入C类子类就是AOP中的一种Advice,如下图:

通过下列代码说明如何使用Picocontainer实现AOP,该例程主要实现是记录logger功能,通过Picocontainer可以使用简单一行,使所有的应用类的记录功能激活。

首先编制一个记录接口:

  public void enableLogging(Log log);

}

有一个LogSwitcher类,主要用来激活具体应用中的记录功能:

一般的普通应用JavaBeans都可以继承这个类,假设PicoUserManager是一个用户管理类,代码如下:

  ..... //用户管理功能

}

public class PicoXXXX1Manager extends LogSwitcher

{

  ..... //业务功能

}

public class PicoXXXX2Manager extends LogSwitcher

{

  ..... //业务功能

}

注意LogSwitcher中Log实例是由外界赋予的,也就是说即将被外界注射进入,下面看看使用Picocontainer是如何注射Log的具体实例的。

Logging logging = (Logging) container.getComponentMulticaster();

logging.enableLogging(new SimpleLog("pico"));//激活log

 

由上代码可见,通过使用简单一行logging.enableLogging()方法使所有的应用类的记录功能激活。这是不是类似AOP的advice实现?

总之,使用Ioc模式,可以不管将来具体实现,完全在一个抽象层次进行描述和技术架构,因此,Ioc模式可以为容器、框架之类的软件实现提供了具体的实现手段,属于架构技术中一种重要的模式应用。J道的

使用了Ioc模式,

是一个IOC/DI成熟应用。

|

|

浅谈IOC--说清楚IOC是什么_哲-CSDN博客_ioc

转载自:http://www.cnblogs.com/DebugLZQ/archive/2013/06/05/3107957.html

https://segmentfault.com/a/1190000014803412

1.IOC的理论背景

2.什么是IOC

3.IOC也叫依赖注入(DI)

4.IOC的优缺点

5.IOC容器的技术剖析

6.IOC容器的一些产品

7.参考博文

本文旨在用语言(非代码)说清楚IOC到底是什么,没有什么高深的技术,园中的老牛、大虾们看到这里可以绕行了,以免浪费您宝贵的时间。IOC这个东西DebugLZQ早就想写了,但是出于对文章权威性的考虑(不能误人子弟- -!),本文主要内容来源于最近LZ看的一些国内外的关于IOC的博文、博问,所有引用到的文章,在

中均已注明。

我们知道在面向对象设计的软件系统中,它的底层都是由N个对象构成的,各个对象之间通过相互合作,最终实现系统地业务逻辑[1]。

  图1 软件系统中耦合的对象

  如果我们打开机械式手表的后盖,就会看到与上面类似的情形,各个齿轮分别带动时针、分针和秒针顺时针旋转,从而在表盘上产生正确的时间。图1中描述的就是这样的一个齿轮组,它拥有多个独立的齿轮,这些齿轮相互啮合在一起,协同工作,共同完成某项任务。我们可以看到,在这样的齿轮组中,如果有一个齿轮出了问题,就可能会影响到整个齿轮组的正常运转。

  齿轮组中齿轮之间的啮合关系,与软件系统中对象之间的耦合关系非常相似。对象之间的耦合关系是无法避免的,也是必要的,这是协同工作的基础。现在,伴随着工业级应用的规模越来越庞大,对象之间的依赖关系也越来越复杂,经常会出现对象之间的多重依赖性关系,因此,架构师和设计师对于系统的分析和设计,将面临更大的挑战。对象之间耦合度过高的系统,必然会出现牵一发而动全身的情形。

  图2 对象之间的依赖关系

  耦合关系不仅会出现在对象与对象之间,也会出现在软件系统的各模块之间,以及软件系统和硬件系统之间。如何降低系统之间、模块之间和对象之间的耦合度,是软件工程永远追求的目标之一。为了解决对象之间的耦合度过高的问题,软件专家Michael Mattson 1996年提出了IOC理论,用来实现对象之间的“解耦”,目前这个理论已经被成功地应用到实践当中。

  IOC是Inversion of Control的缩写,多数书籍翻译成“控制反转”。

  1996年,Michael Mattson在一篇有关探讨面向对象框架的文章中,首先提出了IOC 这个概念。对于面向对象设计及编程的基本思想,前面我们已经讲了很多了,不再赘述,简单来说就是把复杂系统分解成相互合作的对象,这些对象类通过封装以后,内部实现对外部是透明的,从而降低了解决问题的复杂度,而且可以灵活地被重用和扩展。

  

如下图:

图3 IOC解耦过程

  大家看到了吧,由于引进了中间位置的“第三方”,也就是IOC容器,使得A、B、C、D这4个对象没有了耦合关系,齿轮之间的传动全部依靠“第三方”了,全部对象的控制权全部上缴给“第三方”IOC容器,所以,IOC容器成了整个系统的关键核心,它起到了一种类似“粘合剂”的作用,把系统中的所有对象粘合在一起发挥作用,如果没有这个“粘合剂”,对象与对象之间会彼此失去联系,这就是有人把IOC容器比喻成“粘合剂”的由来。

  我们再来做个试验:把上图中间的IOC容器拿掉,然后再来看看这套系统:

图4 拿掉IOC容器后的系统

  我们现在看到的画面,就是我们要实现整个系统所需要完成的全部内容。这时候,A、B、C、D这4个对象之间已经没有了耦合关系,彼此毫无联系,这样的话,当你在实现A的时候,根本无须再去考虑B、C和D了,对象之间的依赖关系已经降低到了最低程度。所以,如果真能实现IOC容器,对于系统开发而言,这将是一件多么美好的事情,参与开发的每一成员只要实现自己的类就可以了,跟别人没有任何关系!

    我们再来看看,控制反转(IOC)到底为什么要起这么个名字?我们来对比一下:

    软件系统在没有引入IOC容器之前,如图1所示,对象A依赖于对象B,那么对象A在初始化或者运行到某一点的时候,自己必须主动去创建对象B或者使用已经创建的对象B。无论是创建还是使用对象B,控制权都在自己手上。

    软件系统在引入IOC容器之后,这种情形就完全改变了,如图3所示,由于IOC容器的加入,对象A与对象B之间失去了直接联系,所以,当对象A运行到需要对象B的时候,IOC容器会主动创建一个对象B注入到对象A需要的地方。

    通过前后的对比,我们不难看出来:

  2004年,Martin Fowler探讨了同一个问题,

控制被反转之后,获得依赖对象的过程由自身管理变为了由IOC容器主动注入。于是,他给“控制反转”取了一个更合适的名字叫做“依赖注入(Dependency Injection)”。他的这个答案,实际上给出了实现IOC的方法:注入。

  所以,依赖注入(DI)和控制反转(IOC)是从不同的角度的描述的同一件事情,就是指通过引入IOC容器,利用依赖关系注入的方式,实现对象之间的解耦。

  学过IOC的人可能都看过Martin Fowler(老马,2004年post)的这篇文章:Inversion of Control Containers and the Dependency Injection pattern[2]。

  博客园的园友EagleFish(邢瑜琨)的文章:

[3]对老马那篇经典文章进行了解读。

    CSDN黄忠成的

[4]也是,不过他应该来自台湾省,用的是繁体,看不管繁体中文的,可以看园中的吕震宇博友的简体中文版

[5] 。

 In my experience, IoC using the Spring container brought the following advantages[6]:

  使用IOC框架产品能够给我们的开发过程带来很大的好处,但是也要充分认识引入IOC框架的缺点,做到心中有数,杜绝滥用框架[1]。

    第一、软件系统中由于引入了第三方IOC容器,生成对象的步骤变得有些复杂,本来是两者之间的事情,又凭空多出一道手续,所以,我们在刚开始使用IOC框架的时候,会感觉系统变得不太直观。所以,引入了一个全新的框架,就会增加团队成员学习和认识的培训成本,并且在以后的运行维护中,还得让新加入者具备同样的知识体系。

    第二、由于IOC容器生成对象是通过反射方式,在运行效率上有一定的损耗。如果你要追求运行效率的话,就必须对此进行权衡。

    第三、具体到IOC框架产品(比如:Spring)来讲,需要进行大量的配制工作,比较繁琐,对于一些小的项目而言,客观上也可能加大一些工作成本。

    第四、IOC框架产品本身的成熟度需要进行评估,如果引入一个不成熟的IOC框架产品,那么会影响到整个项目,所以这也是一个隐性的风险。

    我们大体可以得出这样的结论:一些工作量不大的项目或者产品,不太适合使用IOC框架产品。另外,如果团队成员的知识能力欠缺,对于IOC框架产品缺乏深入的理解,也不要贸然引入。最后,特别强调运行效率的项目或者产品,也不太适合引入IOC框架产品,像WEB2.0网站就是这种情况。

  

,目前.Net C#、Java和PHP5等语言均支持,其中PHP5的技术书籍中,有时候也被翻译成“映射”。有关反射的概念和用法,大家应该都很清楚,通俗来讲就是根据给出的类名(字符串方式)来动态地生成对象。这种编程方式可以让对象在生成时才决定到底是哪一种对象。反射的应用是很广泛的,很多的成熟的框架,比如象Java中的Hibernate、Spring框架,.Net中 NHibernate、Spring.Net框架都是把“反射”做为最基本的技术手段。

  Sun ONE技术体系下的IOC容器有:轻量级的有Spring、Guice、Pico Container、Avalon、HiveMind;重量级的有EJB;不轻不重的有JBoss,Jdon等等。Spring框架作为Java开发中SSH(Struts、Spring、Hibernate)三剑客之一,大中小项目中都有使用,非常成熟,应用广泛,EJB在关键性的工业级项目中也被使用,比如某些电信业务。

    .Net技术体系下的IOC容器有:Spring.Net、Castle等等。Spring.Net是从Java的Spring移植过来的IOC容器,Castle的IOC容器就是Windsor部分。它们均是轻量级的框架,比较成熟,其中Spring.Net已经被广泛应用于各种项目中。

  总之就是很多很多,不甚枚举.....

[1]

---IoC框架 ,王泽宾,CSDN, 2009.

[2]

,Martin Fowler,2004.

[3]

,EagleFish(邢瑜琨), 博客园, 2007.

[4]

 ,黄忠成, CSDN, 2006.

[5]

 ,吕震宇,博客园, 2006.

[6]

扫一扫,分享内容

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。

2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

IOC容器到底是什么-CSDN社区

6.7w+

社区成员

22.5w+

社区内容

控制反转_百度百科

致力于权威的科学传播

西南大学

百度知道 - 信息提示

 | 

 | 

京ICP证030173号-1   京网文【2013】0934-983号     ©2022Baidu  

 | 

 

什么是AOP?怎么理解AOP与IOC?--CSDN问答

整理了半天的文档,就知道AOP是面向切面编程降低耦合度的。求大神解答

个人理解

IOC:控制反转(DI依赖注入),将以前由我们自己手动创建对象的过程交给了Spring,Spring帮助我们生产对象、管理对象、管理对象和对象之间的依赖关系。降低了代码的耦合度,方便我们后期对项目做维护。

三种注入方式:

1.setter注入

2.构造器注入

3.属性注入(注解)

@Autowired:默认根据类型进行匹配

@Resource:首先根据名称进行匹配,再根据类型进行匹配

自动装配autowire属性

AOP:面向切面(方便)编程,可以为某一类对象 进行监督和控制,也就是在调用这类对象的具体方法的前后去调用你指定的功能模块,从而达到对一个模块扩充的功能。可以通过注解或者XML文档进行实现。  

开发切面,切面里面写的功能模块,叫做通知。

前置通知@Before、后置通知@AfterReturning、最终通知@After、异常通知@AfterThrowing、环绕通知@Around

后置通知和最终通知的区别:

后置通知只有在方法正常执行后才会被调用,如果方法执行过程中报错,则不会执行后置通知,而是执行异常通知。

无论方法执行有没有报错,都会执行最终通知

AOP最重要的一个应用:Spring的事务管理器。

Spring的事务管理器就是一个切面,切面中的功能不再是计算时间、输出日志,而是管理事务。因为Spring的事务管理器要对一组数据库操作做事务控制。所以事务管理器需要切入到一个可以包含所有Dao操作的方法中,即Service方法。

Spring事务管理器的特点:所有的事务,要么同时提交,要么同时回滚。只要有一次失误失败,所有事务一起回滚。

JDBC事务的特点:每执行完一次数据库操作就提交一次事务。

报告相同问题?

spring中的IOC是什么,为什么要使用IOC而不是new来创建实例 - 简书

1 背景介绍

spring是什么?

    一个为了解决企业应用开发的复杂性而创建的开源框架,一个轻量级的控制反转(IOC)面向切面(AOP)的容器框架

2 知识剖析

spring中的IOC是什么意思?

    spring通过IOC即反转控制促进了松耦合,一个对象依赖的其他对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖的对象

为什么要使用IOC而不是new来创建实例?

    调用者直接使用new创建被调用者的实例,两者之间的耦合度很高

要由调用者亲自创建被调用者的实例对象,不利于软件的移植与维护

3 常见问题

IOC有哪些缺点?

    创建对象的步骤变复杂了

    通过反射来创建对象,会造成效率上的损耗

    缺少IDE重构的支持,如果修改了类名还需要到XML文件中手动修改

4 解决方案

    相比IOC的灵活性和可维护性来说,这点缺点可以忍受

5 编码实战

一个配置文件

 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">

         class="org.springframework.jdbc.datasource.DriverManagerDataSource">

         class="com.StudentJDBCTemplate">

负责实现的主函数(进行了创建和修改两种操作)

package com;

import java.util.List;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.StudentJDBCTemplate;

public class MainApp {

public static void main(String[] args) {

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

       StudentJDBCTemplate studentJDBCTemplate = (StudentJDBCTemplate)context.getBean("studentJDBCTemplate");

       System.out.println("Records Creation");

       studentJDBCTemplate.create("韩",12);

//        List students = studentJDBCTemplate.listStudents();

//        for (Student record:students) {

//            System.out.println("ID:" + record.getId());

//            System.out.println(", Name : " + record.getName());

//        }

       System.out.println("update start");

       studentJDBCTemplate.update(12,"韩大师");

//        studentJDBCTemplate.delete(12);

   }

}

JDBCTemplate

package com;

import java.util.List;

import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;

public class StudentJDBCTemplate implements StudentDAO{

private DataSource dataSource;

private JdbcTemplate jdbcTemplateObject;

public void setDataSource(DataSource dataSource) {

this.dataSource = dataSource;

       this.jdbcTemplateObject = new JdbcTemplate(dataSource);

   }

public void create(String name,Integer ID) {

String SQL = "insert into student (name,ID) values (?,?)";

       jdbcTemplateObject.update(SQL,name,ID);

return;

   }

//    @Override

//    public Student getStudent(Integer ID) {

//        String SQL = "select * from student where id = ?";

//        Student student = jdbcTemplateObject.query(SQL,new Object[]{ID}, new StudentMapper());

//        return student;

//    }

   @Override

   public List listStudents() {

String SQL = "select * from student";

       List students = jdbcTemplateObject.query(SQL,new StudentMapper());

return students;

   }

@Override

   public void delete(Integer ID) {

String SQL = "delete from student where ID = ?";

       jdbcTemplateObject.update(SQL,ID);

       System.out.println("Deleted Record with ID =" + ID);

return;

   }

@Override

   public void update(Integer ID, String name) {

String SQL = "update student set name = ? where ID = ?";

       jdbcTemplateObject.update(SQL,name,ID);

       System.out.println("Updated Record with ID = "+ ID);

return;

   }

}

6 扩展思考

spring控制反转是控制什么反转

    IOC控制反转,强调容器的作用,用于组织或控制容器内bean的运行,把传统上有程序代码直接操控的对象的调用权交给容器

7 参考文献

    w3cschool spring 概述

    百度

8 更多讨论

什么是bean?

    由IOC容器管理的那些组成应用程序的对象就是bean,是由spring容器初始化,装配以及管理的对象。

9 提问

spring的依赖注入有什么优势?

spring的依赖注入有四种方式:Setter方法注入;构造方法注入;静态工厂的方法注入;实例工厂的方法注入

让使用者不需要自己去创建或获取自己的依赖,既然创建或获取的过程不是使用者控制的,这也就意味着,当我需要切换依赖时,不需要改变使用者的代码

@Autowired和@Resource的区别?

@Autowired  默认按类型装配 

 依赖对象必须存在,如果要允许null值,可以设置它的required属性为false   @Autowired(required=false)

 也可以使用名称装配,配合@Qualifier注解

@Resource  默认按名称进行装配,通过name属性进行指定

大白话解释,@Autowired自动注解,举个例子吧,一个类,俩个实现类,Autowired就不知道注入哪一个实现类,而Resource有name属性,可以区分。

By Type和 By Name的区别?

byName 通过参数名 自动装配,如果一个bean的name 和另外一个bean的 property 相同,就自动装配。

byType   通过参数的数据类型自动自动装配,如果一个bean的数据类型和另外一个bean的property属性的数据类型兼容,就自动装配

spring注入bean的方式有哪些?

首先要配置被注入的bean,在该bean对应的类中,应该有要注入的对象属性或者基本数据类型的属性。

UserBiz类注入UserDAO,同时为UserBiz注入基本数据类型String,那么这时,就要为UserDAO对象和String类型设置setter方法.,用于进行依赖注入。

如何配置该bean呢?

userDao

第一,在PersonBiz类中注入PersonDAO和一个String类型的数据;在该类中,不用为PersonDAO属性和String数据类型的属性设置setter方法,但是需要生成该类的构造方法;

第二,在配置文件中配置该类的bean,并配置构造器,在配置构造器中用到了节点,该节点有四个属性:

· index是索引,指定注入的属性,从0开始,如:0代表personDao,1代表str属性;

· type是指该属性所对应的类型,如Persondao对应的是com.aptech.dao.PersonDAO;

· ref 是指引用的依赖对象;

· value 当注入的不是依赖对象,而是基本数据类型时,就用value;