IOC是什么意思英语 解析ioc概念与应用?

  大家知道ioc是什么意思吗?随着时代的发展,越来越多的的新词汇出现在我们的生活中,下面就和康网小编一起来了解一下ioc是什么意思吧。  ioc是什么意思:  控制反转(Inversion of Control,英文缩写为Ioc)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心。 控制反转一般分为两种类型,依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)。依赖注入应用比较广泛。  起源:  早在2004年,Martin Fowler就提出了“哪些方面的控制被反转了?”这个问题。他总结出是依赖对象的获得被反转了。基于这个结论,他为控制反转创造了一个更好的名字:依赖注入。许多非凡的应用(比HelloWorld.java更加优美,更加复杂)都是由两个或是更多的类通过彼此的合作来实现业务逻辑,这使得每个对象都需要,与其合作的对象(也就是它所依赖的对象)的引用。如果这个获取过程要靠自身实现,那么如你所见,这将导致代码高度耦合并且难以测试。  IoC 亦称为 “依赖倒置原理”("Dependency Inversion Principle")。差不多所有框架都使用了“倒置注入(Fowler 2004)技巧,这可说是IoC原理的一项应用。SmallTalk,C++, Java 或.NET 等各种面向对象程序语言的程序员已使用了这些原理。  控制反转是Spring框架的核心。  应用控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用,传递给它。也可以说,依赖被注入到对象中。所以,控制反转是,关于一个对象如何获取他所依赖的对象的引用,这个责任的反转。  设计模式:  oC就是IoC,不是什么技术,与GoF一样,是一种设计模式。  Interface Driven Design接口驱动,接口驱动有很多好处,可以提供不同灵活的子类实现,增加代码稳定和健壮性等等,但是接口一定是需要实现的,也就是如下语句迟早要执行:AInterface a = new AInterfaceImp(); 这样一来,耦合关系就产生了。  Class A与AInterfaceImp就是依赖关系,如果想使用AInterface的另外一个实现就需要更改代码了。当然我们可以建立一个Factory来根据条件生成想要的AInterface的具体实现。  表面上是在一定程度上缓解了以上问题,但实质上这种代码耦合并没有改变。通过IoC模式可以彻底解决这种耦合,它把耦合从代码中移出去,放到统一的XML 文件中,通过一个容器在需要的时候把这个依赖关系形成,即把需要的接口实现注入到需要它的类中,这可能就是“依赖注入”说法的来源了。  IOC模式,系统中通过引入实现了IOC模式的IOC容器,即可由IOC容器来管理对象的生命周期、依赖关系等,从而使得应用程序的配置和依赖性规范与实际的应用程序代码分开。其中一个特点就是通过文本的配置文件进行应用程序组件间相互关系的配置,而不用重新修改并编译具体的代码。  当前比较知名的IOC容器有:Pico Container、Avalon 、Spring、JBoss、HiveMind、EJB等。  在上面的几个IOC容器中,轻量级的有Pico Container、Avalon、Spring、HiveMind等,超重量级的有EJB,而半轻半重的有容器有JBoss,Jdon等。  可以把IoC模式看做是工厂模式的升华,可以把IoC看作是一个大工厂,只不过这个大工厂里要生成的对象都是在XML文件中给出定义的,然后利用Java 的“反射”编程,根据XML中给出的类名生成相应的对象。从实现来看,IoC是把以前在工厂方法里写死的对象生成代码,改变为由XML文件来定义,也就是把工厂和对象生成这两者独立分隔开来,目的就是提高灵活性和可维护性。  IoC中最基本的Java技术就是“反射”编程。反射又是一个生涩的名词,通俗的说反射就是根据给出的类名(字符串)来生成对象。这种编程方式可以让对象在生成时才决定要生成哪一种对象。反射的应用是很广泛的,象Hibernate、Spring中都是用“反射”做为最基本的技术手段。  在过去,反射编程方式相对于正常的对象生成方式要慢10几倍,这也许也是当时为什么反射技术没有普通应用开来的原因。但经SUN改良优化后,反射方式生成对象和通常对象生成方式,速度已经相差不大了(但依然有一倍以上的差距)。  扩展阅读:ioc的优缺点  IoC最大的好处是什么?  因为把对象生成放在了XML里定义,所以当我们需要换一个实现子类将会变成很简单(一般这样的对象都是实现于某种接口的),只要修改XML就可以了,这样我们甚至可以实现对象的热插拔(有点象USB接口和SCSI硬盘了)。  IoC最大的缺点是什么?  (1)生成一个对象的步骤变复杂了(事实上操作上还是挺简单的),对于不习惯这种方式的人,会觉得有些别扭和不直观。  (2)对象生成因为是使用反射编程,在效率上有些损耗。但相对于IoC提高的维护性和灵活性来说,这点损耗是微不足道的,除非某对象的生成对效率要求特别高。  (3)缺少IDE重构操作的支持,如果在Eclipse要对类改名,那么你还需要去XML文件里手工去改了,这似乎是所有XML方式的缺憾所在。
ioc的概念介绍控制反转(ioc)模式(又称di:dependency injection)就是inversion of control,控制反转。在java开发中,ioc意 味着将你设计好的类交给系统去控制,而不是在你的类内部控制。这称为控制反转。控制反转(inversion of control,英文缩写为ioc)是框架的重要特征,做到控制反转需要一个容器来实现,就是我们所说的ioc容器,最常见的ioc容器是spring。控制反转从字面意思看来不是很好理解,其实就是将创建管理对象的工作交给容器来做。在以前的编程中,创建一个对象需要显式的new出来,但是控制反转是在容器初始化(或者某个指定时间节点)时通过反射机制(上一篇文章有介绍)创建好对象,在使用时去容器中获取。将对象的控制权反过来交给容器管理,所以称之为“控制反转”。一、ioc容器是怎么实现的呢?ioc容器的底层实现其实是工厂模式,通过工厂模式和反射机制,根据xml中给出的类名生成相应的对象。其实ioc容器的实现很简单,就是一个hashmap,接下来,我们实现一个简单的ioc容器:1.读取配置文件,并初始化容器配置文件可以是xml或者properties文件,下面代码是读取两种配置文件创建实例,并放到容器中(容器的实现是hashmap):(1)读取xml配置文件,创建实例放进容器的实现:读取xml创建容器(2)读取properties文件,创建实例放进容器的实现:读取properties创建容器2.applicationcontextfactory工厂的实现(调用初始化容器的方法)通过工厂创建应用上下文中配置的对象,在此工厂中判断是否存在xml或prop文件,并初始化容器:applicationcontextfactory工厂的实现3.容器的使用通过工厂创建完容器就可以使用了,调用getbean(string beanid)方法获取容器中的对象实例:容器的使用二、依赖注入(di,dependency injection)和依赖查找(dependency lookup)是什么?依赖注入和依赖查找是ioc的两种主要实现方式,我直接把依赖查找给扔了没去理解他,一般会把ioc和di放在一起说。其实可以把di和ioc理解为同一件事,都是把创建实例的控制权交给容器来操作,只是两种叫法的角度不同:控制反转是从代码操作对象的角度来看,将操作对象的控制权反转交给了容器;依赖注入是从容器的角度看,我把你需要的对象或属性注入到你代码中去。希望与广大网友互动??点此进行留言吧!
您愿意向朋友推荐“博客详情页”吗?
强烈不推荐
不推荐
一般般
推荐
强烈推荐
spring核心两大核心内容为ioc和aop。本章节讲ioc的概念、作用和使用方式。ioc简单介绍:概念:控制反转,把对象创建和对象之间的调用过程,交给Spring管理目的是降低耦合底层原理:xml解析、工厂模式、反射.过程:1 xml解析得到类的全路径 ApplicationContext applicationContext =new
ClassPathXmlApplicationContext("bean.xml");
2 通过反射创建对象3 通过工厂类返回
User user
=applicationContext.getBean("user",User .class);
Ioc思想基于ioc容器完成,ioc容器本质上就是对象工厂。spring提供ioc容器实现两种方式:(两个接口)1.BeanFactory:Ioc容器基本实现,是Spring内部的使用接口,不提供开发人员进行使用ps:加载配置文件的时候不会创建对象,在获取对象使用才会去创建对象2.ApplicationContext:有两个实现类:不同在于FileSystemXmlApplicationContext是传绝对路径,ClassPathXmlApplicationContext是传在项目中的相对路径。ApplicationContext applicationContext =new
ClassPathXmlApplicationContext("bean.xml");
User user
=applicationContext.getBean("user",User .class);
ioc管理对象:(指的是创建对象和注入属性)1.基于xml配置文件2.基于注解方式基于xml方式:1.基于xml方式创建对象使用bean标签 id:唯一属性 class:类全路径 <bean id="user" class="com.wsl.spring.dao.UserDao" ></bean>
2.基于xml方式注入属性DI:依赖注入,是ioc注入属性的具体实现2.1.基于set注入 :使用property注解 <bean id="user" class="com.wsl.spring.pojo.User" >
<property name="name" value="小红"></property>
<property name="age" value="11"></property>
</bean>
2.2.基于有参构造器注入<bean id="user" class="com.wsl.spring.pojo.User" >
<constructor-arg index="0" value="小绿"></constructor-arg>
<constructor-arg index="1" value="22"></constructor-arg>
</bean>
如果set注入和构造器注入都写了,先执行构造器,再执行set2.3.p命名空间注入可以简化基于xml方式注入1.在配置文件中添加p命名空间 <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
**xmlns:p="http://www.springframework.org/schema/p"**
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
2.使用p注入 <bean id="user" class="com.wsl.spring.pojo.User"
p:age="33" p:name="小兰">
</bean>
ps:特殊符号处理1.转义2.CDATA格式bean在Spring中,那些组成应用程序的主体及由Spring IoC容器所管理的对象,被称之为bean。简单地讲,bean就是由IoC容器初始化、装配及管理的对象spring中有两种bean,一种是普通bean,一种是工厂bean FactoryBean (不是beanEactory 不一样的)普通bean:在配置文件中定义bean类型就是返回类型工厂bean:在配置文件中定义bean类型可以和返回类型不一样Step1:创建类,让这个类作为工厂bean,实现接口FactoryBeanStep2:实现接口的方法,在实现的方法中定义返回的类型。bean的作用域:spring中默认是单实例的,在加载spring配置文件的时候就会创建单实例对象。设置为prototype的时候,在调用getBean的时候才会创建多实例对象。bean的生命周期:bean对象从创建到销毁的过程。1.通过构造器创建bean实例2.为bean的属性设置值和对其他bean的引用(调用set)3.实现后置处理器,在初始化前做一些工作4.调用bean的初始化(需要配置初始化方法)init-method配置5.实现后置处理器,在初始化后做一些工作6.使用bean7.当容器关闭,调用bean的销毁方法(需要配置销毁的方法)destroy-method配置 <bean id="user" class="com.wsl.spring.pojo.User"
p:age="33" p:name="小兰" init-method="init" destroy-method="destory">
</bean>
注解方式@PostConstruct
protected void init()
{
System.out.println("init();");
}
@PreDestroy
protected void destory()
{
System.out.println("destory();");
}
后置处理器 :实现 BeanPostProcesser 接口 ,可以在初始化前后进行一些处理工作。外部文件配置bean1.创建文件jdbc.properties#============================#
#===== Database sttings =====#
#============================#
#oracle database settings
#jdbc.type=oracle
#jdbc.driver=oracle.jdbc.driver.OracleDriver
#jdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
#jdbc.username=jeesite
#jdbc.password=123456
2.引入文件并注入bean<!-- 加载配置属性文件 -->
<context:property-placeholder ignore-unresolvable="true" location="classpath:jdbc.properties" />
<!-- bean设置 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="driverClassName" value="${jdbc.driver}" />
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="${jdbc.pool.init}" />
<property name="minIdle" value="${jdbc.pool.minIdle}" />
<property name="maxActive" value="${jdbc.pool.maxActive}" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
</bean>
1.开启组件扫描component-scan 指定注解扫描包
<context:component-scan base-package="com.wsl"></context:component-scan>
或者直接使用@ComponentScan注解2.在需要扫描的类上面加注解@Component@Component("user")
// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
@Component三个衍生注解为了更好的进行分层,Spring可以使用其它三个注解,功能一样,目前使用哪一个功能都一样。@Controller:controller层@Service:service层@Repository:dao层3.基于注解实现属性注入1.@Autowired在使用@Autowired时,首先在容器中查询对应类型的bean
    如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据
    如果查询的结果不止一个,那么@Autowired会根据名称来查找。
    如果查询的结果为空,那么会抛出异常。解决方法时,使用required=false
2.@Qualifier@Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配
@Qualifier不能单独使用。
3.@Resource**@Autowired与@Resource异同:
1、@Autowired与@Resource都可以用来装配bean。都可以写在字段上,或写在setter方法上。
2、@Autowired默认按类型装配(属于spring规范),默认情况下必须要求依赖对象必须存在,
如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false)
,如果我们想使用名称装配可以结合@Qualifier注解进行使用
3、@Resource(属于J2EE复返),默认按照名称进行装配,名称可以通过name属性进行指定。
如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在
setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。
但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
它们的作用相同都是用注解方式注入对象,但执行顺序不同。@Autowired先byType,@Resource先byName。**
其他注解:@Value用这个注解注入属性1.直接写值2.可以写SpEl #{ }3 ${ } 格式 可以取出配置文件中的值 但需要先用注解@PropertySource(“os.properties”)取到配置文件、在运行环境变量里面的值
@Value("小红")
private String name;
@Value("#{20-2}")
private int age;
// 相当于配置文件中 <property name="name" value="小红"/>
@Value(${os.name}) //需要在类上面使用PropertySource注解
private String os;
//
类似xml中先用<context:property-placeholder >引入外部文件 再用${}取值
@Scope指定bean作用域:singleton prototype request session@LazyBean是针对单实例bean,默认情况下单实例bean是在容器加载的时候创建的。而懒加载在容器加载时候不创建bean,在第一次使用bean的时候才会创建和初始化。按照一定的条件进行判断,满足条件向容器注册bean。可用于类和方法编写两个类,分别实现Condition接口。//linux环境下返回true
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String os = context.getEnvironment().getProperty("os.name");
return os.contains("Linux");
}
}
//windows环境下返回true
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String os =context.getEnvironment().getProperty("os.name");
return os.contains("Windows");
}
}
然后在需要判断的bean上加注解@Conditional和用于判断的类名,在满足该类实现的matches方法时,会向容器注册该bean,否则不注册。也可以用于类上面,作用于该类所有的bean。@Configuration
public class BeanConfig {
@Conditional(WindowsCondition.class)
@Bean("windows-张三")
public User getUser(){
return new User("windows-张三",11);
}
@Conditional(LinuxCondition.class)
@Bean("linux-张三")
public User getUser1(){
return new User("linux-张三",11);
}
}
@import快速导入一个组件@PropertySource引入外部文件 类似xml中先用<context:property-placeholder >@Primary在spring 中使用注解,常使用@Autowired, 默认是根据类型Type来自动注入的。但有些特殊情况,对同一个接口,可能会有几种不同的实现类,而默认只会采取其中一种的情况下 @Primary 的作用就出来了,告诉spring 在犹豫的时候优先选择哪一个具体的实现。@Inject1、@Inject是JSR330 (Dependency Injection for Java)中的规范,需要导入javax.inject.Inject;实现注入。2、@Inject是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Named;3、@Inject可以作用在变量、setter方法、构造函数上。a、将@Inject可以作用在变量、setter方法、构造函数上,和@Autowired一样b、@Named@Named(“XXX”) 中的 XX是 Bean 的名称,所以 @Inject和 @Named结合使用时,自动注入的策略就从 byType 转变成 byName 了。@Profile指定这个bean在该环境下才能注册到容器中去自动装配是使用spring满足bean依赖的一种方法spring会在应用上下文中为某个bean寻找其依赖的bean。Spring中bean有三种装配机制,分别是:在xml中显式配置;在java中显式配置;隐式的bean发现机制和自动装配。自动装配:根据指定装配规则(属性名称或者属性类型),将匹配的属性值进行注入。Spring的自动装配需要从两个角度来实现,或者说是两个操作:组件扫描(component scanning):spring会自动发现应用上下文中所创建的bean;自动装配(autowiring):spring自动满足bean之间的依赖,也就是我们说的IoC/DI;组件扫描和自动装配组合发挥巨大威力,使得显示的配置降低到最少。总结:给容器中注册组件:1.包扫描+组件标注注解(@Component @Controller等) 适用于自己编写的类2.@Bean 用于导入的第三方包里的组件3.@import 快速导入一个组件实现ImportSelector 返回需要导入的组件全类名数组ImportBeanDefinitionRegistrar 手动注册Bean4.实现Factory接口(工厂bean)默认获取到的是工厂bean调用getObject创建的对象要获取工厂bean的本事,需要在id前加一个&符号5.自定义组件想要使用Spring底层的一些组件,可以实现XXXAware接口注入;每一个XXXAware都有对应的XXXProcesser,为自定义类注入对应Aware。指定初始化和销毁方法:1.bean标签的init-method和destory-method2.bean class实现InitializingBean(定义初始化方法),实现DisposableBean接口(定义销毁方法)3.JSR250规范中的@PostConstruct 初始化@PreDestory 销毁4。后置处理器 BeanPostProcessor接口两个方法分别在初始化前后工作

我要回帖

更多关于 IOC是什么意思英语 的文章

 

随机推荐