【黑马程序员】Spring的IOC原理

合集下载

ioc的实现原理

ioc的实现原理

IoC(控制反转)的实现原理1. 什么是IoC控制反转(Inversion of Control,简称IoC)是一种设计思想或模式,它的核心思想是将对象的创建和依赖关系的管理交给容器来完成,从而实现了对象之间的解耦。

IoC的目的是降低组件之间的耦合度,提升系统的可维护性和可测试性。

在传统的编程模式中,对象的创建和依赖关系的管理通常由程序员手动创建和维护,而在IoC容器的帮助下,这一过程被自动化地处理了。

2. IoC的基本原理IoC的实现原理主要包括两个核心概念:依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)。

2.1 依赖注入(DI)依赖注入是一种机制,它通过容器将一个对象的依赖关系注入到该对象中,使得对象只需要关注自身的业务逻辑,而不需要关心依赖对象的创建和管理。

通常,依赖注入可以通过构造函数注入、属性注入和方法注入来实现: - 构造函数注入:通过对象的构造函数接收依赖对象。

- 属性注入:通过对象的属性接收依赖对象。

- 方法注入:通过对象的方法接收依赖对象。

依赖注入的核心思想是:将对象之间的依赖关系从代码中解耦出来,交给容器来管理,对象只需要声明自己需要哪些依赖对象,由容器来负责注入。

2.2 依赖查找(DL)依赖查找是指通过容器查找依赖对象的过程。

当一个对象需要获取某个依赖对象时,它可以通过容器来进行查找。

容器将使用一种查找策略来查找对象并返回给请求者。

依赖查找的方式有两种:主动查找和被动查找。

- 主动查找:对象主动向容器请求依赖对象。

- 被动查找:对象被动地等待容器将依赖对象注入。

无论是哪种方式,依赖查找的核心思想是:将对象获取依赖对象的逻辑从对象中解耦出来,由容器统一管理。

2.3 IoC容器IoC容器是IoC模式的核心,它负责创建对象、管理对象和处理对象之间的依赖关系。

在Spring框架中,容器是由BeanFactory和ApplicationContext两个核心接口实现的。

SpringIOC和aop的原理及实例详解

SpringIOC和aop的原理及实例详解

SpringIOC和aop的原理及实例详解这篇⽂章主要介绍了Spring IOC和aop的原理及实例详解,⽂中通过⽰例代码介绍的⾮常详细,对⼤家的学习或者⼯作具有⼀定的参考学习价值,需要的朋友可以参考下Spring是⼀个轻量级的控制反转(IoC)和⾯向切⾯(AOP)的容器框架。

特点是⾯向接⼝编程,松耦合。

1:IOC(控制反转)别名(DI:依赖注⼊)⾸先来⼀段ioc的实现原来代码:public class ClassPathXmlApplicationContext implements BeanFactory {private Map<String , Object> beans = new HashMap<String, Object>();//IOC Inverse of Control DI Dependency Injectionpublic ClassPathXmlApplicationContext() throws Exception {SAXBuilder sb=new SAXBuilder();//解析xml配置⽂件Document doc=sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml"));Element root=doc.getRootElement(); //获取根元素List list=root.getChildren("bean");//根元素下的⼦元素for(int i=0;i<list.size();i++) {Element element=(Element)list.get(i);String id=element.getAttributeValue("id");String clazz=element.getAttributeValue("class");Object o = Class.forName(clazz).newInstance(); //反射获得实例System.out.println(id);System.out.println(clazz);beans.put(id, o);//注⼊bean属性for(Element propertyElement : (List<Element>)element.getChildren("property")) {String name = propertyElement.getAttributeValue("name"); //userDAOString bean = propertyElement.getAttributeValue("bean"); //uObject beanObject = beans.get(bean);//UserDAOImpl instanceString methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);System.out.println("method name = " + methodName);Method m = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);m.invoke(o, beanObject);}}}public Object getBean(String id) {return beans.get(id);}}//xml⽂件<beans><bean id="u" class="erDAOImpl" /><bean id="userService" class="erService" ><property name="userDAO" bean="u"/></bean></beans>以上代码实现了将UserDAOImpl注⼊到userService.值得注意的是:以上操作都是spring帮我们实现的,我们只需要理解如何配置即可。

spring框架的工作原理

spring框架的工作原理

spring框架的工作原理Spring框架的工作原理主要分为以下几个方面:1. 控制反转(IoC): Spring采用了控制反转的设计模式,通过IoC 容器来管理对象的创建和依赖关系的注入。

在传统的开发中,类与类之间的依赖关系通常由类自己维护,而在Spring框架中,依赖关系由Spring容器来管理,开发人员只需要定义好依赖关系,由容器来完成对象的创建和组装。

这种方式可以降低组件之间的耦合度,提高系统的灵活性和可维护性。

2. 面向切面编程(AOP): Spring框架还支持面向切面编程,通过AOP可以在不修改原有业务逻辑的情况下,插入和改变系统的部分功能。

例如,可以使用AOP在事务开始之前开启事务,在事务提交之后关闭事务。

Spring使用AOP代理来实现,它可以基于代理模式或者字节码生成技术实现。

3. 基于注解的开发: Spring框架支持基于注解的开发方式,通过在类、方法或者字段上添加特定的注解,Spring框架可以根据注解的配置信息自动完成对象的创建和属性的注入。

使用注解可以简化配置,减少开发人员的工作量。

4. 模块化设计: Spring框架采用了模块化的设计思想,根据功能的不同划分了不同的模块,例如Spring Core、Spring MVC、Spring Security等。

每个模块都有特定的功能和用途,可以根据需要选择性地引入和使用。

5. 与其他框架的集成: Spring框架可以与其他流行的框架进行集成,例如Hibernate、MyBatis、Struts等。

通过与这些框架的集成,可以更加方便地使用它们的功能,提高开发效率。

总的来说,Spring框架的工作原理是基于控制反转和面向切面编程的,通过IoC容器管理对象的创建和依赖关系注入,同时支持基于注解的开发方式和模块化设计,方便与其他框架集成。

spring源代码IOC之实现原理

spring源代码IOC之实现原理

上一章我们已经初步认识了BeanFactory和BeanDefinition,一个是IOC的核心工厂接口,一个是IOC的bean定义接口,上章提到说我们无法让BeanFactory持有一个Map<String,Object>来完成bean工厂的功能,是因为spring 的初始化是可以控制的,可以到用的时候才将bean实例化供开发者使用,除非我们将bean的lazy-init属性设置为true,初始化bean工厂时采用延迟加载。

那么知道了上述两个接口,我相信不少人甚至不看源码都已经猜到spring是如何做的了。

没错,就是让bean工厂持有一个Map<String,BeanDefinition>,这样就可以在任何时候我们想用哪个bean,取到它的bean定义,我们就可以创造出一个新鲜的实例。

接口当然不可能持有这样一个对象,那么这个对象一定是在BeanFactory的某个实现类或者抽象实现类当中所持有的,我经过跋山涉水,终于把它给找出来了,来看DefaultListableBeanFactory。

/**Copyright2002-2010theoriginalauthororauthors.*LicensedundertheApacheLicense,Version2.0(the"License");*youmaynotusethisfileexceptincompliancewiththeLicense.*YoumayobtainacopyoftheLicenseat*/licenses/LICENSE-2.0*Unlessrequiredbyapplicablelaworagreedtoinwriting,software*distributedundertheLicenseisdistributedonan"ASIS"BASIS,*WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.*SeetheLicenseforthespecificlanguagegoverningpermissionsand*limitationsundertheLicense.*/packageorg.springframework.beans.factory.support;importjava.io.NotSerializableException;importjava.io.ObjectStreamException;importjava.io.Serializable;ng.annotation.Annotation;ng.ref.Reference;ng.ref.WeakReference;ng.reflect.ParameterizedType;ng.reflect.Type;importjava.security.AccessController;importjava.security.PrivilegedAction;importjava.util.ArrayList;importjava.util.Arrays;importjava.util.Collection;importjava.util.HashMap;importjava.util.LinkedHashMap;importjava.util.LinkedHashSet;importjava.util.List;importjava.util.Map;importjava.util.Set;importjava.util.concurrent.ConcurrentHashMap;importjavax.inject.Provider;importorg.springframework.beans.BeansException;importorg.springframework.beans.FatalBeanException;importorg.springframework.beans.TypeConverter;importorg.springframework.beans.factory.BeanCreationException;importorg.springframework.beans.factory.BeanCurrentlyInCreationException; importorg.springframework.beans.factory.BeanDefinitionStoreException; importorg.springframework.beans.factory.BeanFactory;importorg.springframework.beans.factory.BeanFactoryAware;importorg.springframework.beans.factory.BeanFactoryUtils;importorg.springframework.beans.factory.CannotLoadBeanClassException; importorg.springframework.beans.factory.FactoryBean;importorg.springframework.beans.factory.NoSuchBeanDefinitionException; importorg.springframework.beans.factory.ObjectFactory;importorg.springframework.beans.factory.SmartFactoryBean;importorg.springframework.beans.factory.config.BeanDefinition;importorg.springframework.beans.factory.config.BeanDefinitionHolder; importorg.springframework.beans.factory.config.ConfigurableBeanFactory; importorg.springframework.beans.factory.config.ConfigurableListableBeanFactory; importorg.springframework.beans.factory.config.DependencyDescriptor; importorg.springframework.core.annotation.AnnotationUtils;importorg.springframework.util.Assert;importorg.springframework.util.ObjectUtils;importorg.springframework.util.StringUtils;/***Defaultimplementationofthe*{@linkorg.springframework.beans.factory.ListableBeanFactory}and*{@linkBeanDefinitionRegistry}interfaces:afull-fledgedbeanfactory*basedonbeandefinitionobjects.**<p>Typicalusageisregisteringallbeandefinitionsfirst(possiblyread*fromabeandefinitionfile),beforeaccessingbeans.Beandefinitionlookup*isthereforeaninexpensiveoperationinalocalbeandefinitiontable,*operatingonpre-builtbeandefinitionmetadataobjects.**<p>Canbeusedasastandalonebeanfactory,orasasuperclassforcustom*beanfactories.Notethatreadersforspecificbeandefinitionformatsare*typicallyimplementedseparatelyratherthanasbeanfactorysubclasses:*seeforexample{@linkPropertiesBeanDefinitionReader}and*{@linkorg.springframework.beans.factory.xml.XmlBeanDefinitionReader}.**<p>Foranalternativeimplementationofthe*{@linkorg.springframework.beans.factory.ListableBeanFactory}interface,*havealookat{@linkStaticListableBeanFactory},whichmanagesexisting*beaninstancesratherthancreatingnewonesbasedonbeandefinitions.**@authorRodJohnson*@authorJuergenHoeller*@authorSamBrannen*@authorCostinLeau*@since16April2001*@seeStaticListableBeanFactory*@seePropertiesBeanDefinitionReader*@seeorg.springframework.beans.factory.xml.XmlBeanDefinitionReader*/publicclassDefaultListableBeanFactoryextendsAbstractAutowireCapableBeanFactory implementsConfigurableListableBeanFactory,BeanDefinitionRegistry,Serializable{privatestaticClassjavaxInjectProviderClass=null;static{ClassLoadercl=DefaultListableBeanFactory.class.getClassLoader();try{javaxInjectProviderClass=cl.loadClass("javax.inject.Provider");}catch(ClassNotFoundExceptionex){//JSR-330APInotavailable-Providerinterfacesimplynotsupportedthen.}}/**Mapfromserializedidtofactoryinstance*/privatestaticfinalMap<String,Reference<DefaultListableBeanFactory>>serializableFactories= newConcurrentHashMap<String,Reference<DefaultListableBeanFactory>>();/**Optionalidforthisfactory,forserializationpurposes*/privateStringserializationId;/**Whethertoallowre-registrationofadifferentdefinitionwiththesamename*/ privatebooleanallowBeanDefinitionOverriding=true;/**Whethertoalloweagerclassloadingevenforlazy-initbeans*/privatebooleanallowEagerClassLoading=true;/**Resolvertouseforcheckingifabeandefinitionisanautowirecandidate*/ privateAutowireCandidateResolverautowireCandidateResolver=newSimpleAutowireCandidateResolver();/**Mapfromdependencytypetocorrespondingautowiredvalue*/privatefinalMap<Class,Object>resolvableDependencies=newHashMap<Class,Object>();/**Mapofbeandefinitionobjects,keyedbybeanname*/privatefinalMap<String,BeanDefinition>beanDefinitionMap=newConcurrentHashMap<String,BeanDefinition >();/**Listofbeandefinitionnames,inregistrationorder*/privatefinalList<String>beanDefinitionNames=newArrayList<String>();/**Whetherbeandefinitionmetadatamaybecachedforallbeans*/privatebooleanconfigurationFrozen=false;/**Cachedarrayofbeandefinitionnamesincaseoffrozenconfiguration*/privateString[]frozenBeanDefinitionNames;}注明下,这里我省略了下面N多行源码,源码太长,而且太多的话容易混乱,切勿认为此类就这么多了。

Spring IOC 原理通俗解释

Spring IOC 原理通俗解释

Spring IOCIOC(DI):其实这个Spring架构核心的概念没有这么复杂,更不像有些书上描述的那样晦涩。

java程序员都知道:java程序中的每个业务逻辑至少需要两个或以上的对象来协作完成,通常,每个对象在使用他的合作对象时,自己均要使用像new object()这样的语法来完成合作对象的申请工作。

你会发现:对象间的耦合度高了。

而IOC的思想是:Spring容器来实现这些相互依赖对象的创建、协调工作。

对象只需要关系业务逻辑本身就可以了。

从这方面来说,对象如何得到他的协作对象的责任被反转了(IOC、DI)。

这是我对Spring的IOC的体会。

DI其实就是IOC的另外一种说法。

DI是由Martin Fowler 在2004年初的一篇论文中首次提出的。

他总结:控制的什么被反转了?就是:获得依赖对象的方式反转了。

如果对这一核心概念还不理解:这里引用一个叫Bromon的blog上找到的浅显易懂的答案:IoC与DI首先想说说IoC(Inversion of Control,控制倒转)。

这是spring的核心,贯穿始终。

所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。

这是什么意思呢,举个简单的例子,我们是如何找女朋友的?常见的情况是,我们到处去看哪里有长得漂亮身材又好的mm,然后打听她们的兴趣爱好、qq号、电话号、ip号、iq号………,想办法认识她们,投其所好送其所要,然后嘿嘿……这个过程是复杂深奥的,我们必须自己设计和面对每个环节。

传统的程序开发也是如此,在一个对象中,如果要使用另外的对象,就必须得到它(自己new一个,或者从JNDI中查询一个),使用完之后还要将对象销毁(比如Connection等),对象始终会和其他的接口或类藕合起来。

那么IoC是如何做的呢?有点像通过婚介找女朋友,在我和女朋友之间引入了一个第三者:婚姻介绍所。

婚介管理了很多男男女女的资料,我可以向婚介提出一个列表,告诉它我想找个什么样的女朋友,比如长得像李嘉欣,身材像林熙雷,唱歌像周杰伦,速度像卡洛斯,技术像齐达内之类的,然后婚介就会按照我们的要求,提供一个mm,我们只需要去和她谈恋爱、结婚就行了。

springioc的实现原理

springioc的实现原理

springioc的实现原理SpringIOC是Spring框架中最重要的模块,它的主要功能是实现依赖注入(DI),它主要实现了“控制反转”(IoC)的概念,它是一个,它可以管理和控制所有的bean(即组件)。

SpringIOC的实现原理很简单,但有一定的复杂性,主要包括以下几个步骤:1、首先,读取配置文件,解析bean的定义,并根据定义创建bean实例。

2、然后,调用bean的setter方法,设置bean之间的依赖关系,即bean的属性值。

3、接着,初始化bean,调用bean的init方法,完成bean 的初始化工作。

4、最后,将bean注册到IoC中,以便使用者获取bean。

SpringIOC机制有几个优点:1、提高了代码的可重用性:将控制权反转给了组件,使得组件可以被重复利用,提高了代码的可重用性。

2、减少了代码的耦合性:通过依赖注入的方式,将组件之间的依赖关系给减少,减少了代码之间的耦合性,管理bean的生命周期,使得开发人员可以更好的控制bean的状态。

3、提高了代码的可测试性:可以自动检测bean之间的依赖关系,使得开发人员可以更加容易的测试组件。

4、改善了代码的可扩展性:可以轻松的添加新的组件,从而改善代码的可扩展性。

总之,SpringIOC的实现原理就是利用解析bean的定义,并根据定义创建bean实例,调用bean的setter方法,设置bean之间的依赖关系,然后调用bean的init方法,完成bean的初始化工作,最后将bean注册到IoC中,以便使用者获取bean,并可以通过依赖注入的方式,减少组件之间的耦合性,提高代码的可重用性和可测试性,改善代码的可扩展性。

Spring中IOC和AOP的深入讲解

Spring中IOC和AOP的深入讲解

Spring中IOC和AOP的深⼊讲解前⾔Spring是⼀个开源框架,Spring是于2003 年兴起的⼀个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍⽣⽽来。

它是为了解决企业应⽤开发的复杂性⽽创建的。

Spring使⽤基本的JavaBean来完成以前只可能由EJB完成的事情。

然⽽,Spring的⽤途不仅限于服务器端的开发。

从简单性、可测试性和松耦合的⾓度⽽⾔,任何Java应⽤都可以从Spring中受益。

简单来说,Spring是⼀个轻量级的控制反转(IoC)和⾯向切⾯(AOP)的容器框架。

这篇⽂章主要讲 Spring 中的⼏个点,Spring 中的 IOC,AOP,下⼀篇说说 Spring 中的事务操作,注解和 XML 配置。

Spring 简介Spring 是⼀个开源的轻量级的企业级框架,其核⼼是反转控制 (IoC) 和⾯向切⾯ (AOP) 的容器框架。

我们可以把 Spring 看成是对象的容器,容器中可以包含很多对象,所以 Spring 有很多强⼤的功能。

⼀句话,Spring 是项⽬中对象的管家,负责管理项⽬中⽤到的所有对象。

所以在项⽬三层架构中,Spring 不属于某⼀特定层。

Spring 的 Hello World想要构建⼀个 Spring 的⼊门程序,我们需要导⼊ 4 个核⼼包和 2 个辅助包,创建⼀个实体类,最主要的是编写核⼼配置⽂件,applicationContext.xml 放在 src 下。

最后写⼀个测试类即可。

此时在测试类中我们不需要在使⽤ new 关键字去创建对象了。

这也正是 Spring 的作⽤所在,会⾃动给我创建对象。

上图展⽰的就是最基本的演⽰,也是很容易就理解了,配置⽂件中配置了 user 对象,我们通过加载配置⽂件来获取对象从⽽避免了使⽤ new 来创建。

spring ioc 原理 spring aop原理 - 本事记的富伟徐 - javaey

spring ioc 原理 spring aop原理 - 本事记的富伟徐 - javaey

spring ioc 原理spring aop原理- 本事记的富伟徐-JavaEy...1.关于spring ioc 这段时间也着实好好的看了下spring的相关书籍,对其也有了大概和初步的认识和理解,虽然之前也一直听说spring是一个非常优秀的开源框架,可一直没有机会学习和使用(是不是有点落伍了?呵呵),所以呢,这段时间就重点学习了spring(一个星期的时间当然是入门级的啦~~)大家一直都说spring的IOC如何如何的强大,其实我倒觉得不是IOC如何的强大,说白了IOC 其实也非常的简单。

我们先从IOC说起,这个概念其实是从我们平常new一个对象的对立面来说的,我们平常使用对象的时候,一般都是直接使用关键字类new一个对象,那这样有什么坏处呢?其实很显然的,使用new那么就表示当前模块已经不知不觉的和new的对象耦合了,而我们通常都是更高层次的抽象模块调用底层的实现模块,这样也就产生了模块依赖于具体的实现,这样与我们JA V A中提倡的面向接口面向抽象编程是相冲突的,而且这样做也带来系统的模块架构问题。

很简单的例子,我们在进行数据库操作的时候,总是业务层调用DAO层,当然我们的DAO一般都是会采用接口开发,这在一定程度上满足了松耦合,使业务逻辑层不依赖于具体的数据库DAO层。

但是我们在使用的时候还是会new一个特定数据库的DAO层,这无形中也与特定的数据库绑定了,虽然我们可以使用抽象工厂模式来获取DAO实现类,但除非我们一次性把所有数据库的DAO写出来,否则在进行数据库迁移的时候我们还是得修改DAO工厂类。

那我们使用IOC能达到什么呢?IOC,就是DAO接口的实现不再是业务逻辑层调用工厂类去获取,而是通过容器(比如spring)来自动的为我们的业务层设置DAO的实现类。

这样整个过程就反过来,以前是我们业务层主动去获取DAO,而现在是DAO主动被设置到业务逻辑层中来了,这也就是反转控制的由来。

【黑马程序员】关于spring的面试和笔试题(一)的副本 5

【黑马程序员】关于spring的面试和笔试题(一)的副本 5

【黑马程序员】关于spring的面试和笔试题(一)1. 什么是spring?Spring 是个java企业级应用的开源开发框架。

Spring主要用来开发Java应用,但是有些扩展是针对构建J2EE平台的web应用。

Spring 框架目标是简化Java企业级应用开发,并通过POJO为基础的编程模型促进良好的编程习惯。

2. 使用Spring框架的好处是什么?轻量:Spring 是轻量的,基本的版本大约2MB控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们面向切面的编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开容器:Spring 包含并管理应用中对象的生命周期和配置MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)异常处理:Spring 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate orJDO抛出的)转化为一致的unchecked 异常3. Spring由哪些模块组成?以下是Spring 框架的基本模块:Core moduleBean moduleContext moduleExpression Language moduleJDBC moduleORM moduleOXM moduleJava Messaging Service(JMS)moduleTransaction moduleWeb moduleWeb-Servlet moduleWeb-Struts moduleWeb-Portlet module4. 核心容器(应用上下文) 模块这是基本的Spring模块,提供spring 框架的基础功能,BeanFactory 是任何以spring为基础的应用的核心。

Spring框架之IOC和AOP底层原理

Spring框架之IOC和AOP底层原理

Spring框架之IOC和AOP底层原理<!-- https:///artifact/org.springframework/spring-webmvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.6.RELEASE</version></dependency><!-- https:///artifact/org.springframework/spring-webmvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.2.6.RELEASE</version></dependency>1.2优点:Spring是⼀个开源的免费的框架(容器)Spring是⼀个轻量级、⾮⼊侵式的框架控制反转(IOC)、⾯向切⾯编程(AOP)⽀持事务的处理,对框架整合的⽀持总结⼀句话:Spring就是⼀个轻量级的控制反转(IOC),和⾯向切⾯编程(AOP)的框架1、3组成1、4拓展Spring官⽹:现代化的开发就是基于java的开发Spring Boot⼀个快速开发的脚⼿架基于SpringBoot可以快速开发单个微服务约定⼤于配置Spring CloudSpringCloud是基于SpringBoot实现的因为现在⼤多数公司都在使⽤SprigBoot进⾏快速开发,学习SpringBoot的前提,需要完全掌握Spring以及SpringMVC!弊端:Spring发展太久,违背了原来的理念!配置⼗分繁琐,⼈称“配置地狱”!2、IOC理论推导1、UserDao接⼝public interface UserDao {void getUser();}2、UserDaoImpl实现类public class UserDaoImpl implements UserDao {public void getUser() {System.out.println("默认获取⽤户的数据");}}3、UserService接⼝public interface UserService {void getUser();}4、UserServiceImpl业务实现类public class UserServiceImpl implements UserService {private UserDao userDao ;//利⽤Set接⼝进⾏动态实现注⼊public void setUserDao(UserDao userDao) {erDao = userDao;}public void getUser() {userDao.getUser();}}在之前的业务中,⽤户的额需求可能会影响到我们原来的代码,我们需要根据⽤户的需求去修改源代码!如果程序代码量⼗分⼤,修改⼀次的成本代价⼗分昂贵!我们使⽤⼀个Set接⼝实现,已经发⽣了⾰命性的改变!//利⽤Set接⼝进⾏动态实现注⼊public void setUserDao(UserDao userDao) {erDao = userDao;}之前,程序是主动创建对象!控制权在程序员⼿上!使⽤了Set注⼊后,程序不再具有主动性,⽽是变成了被动的接收对象这种思想,从本质上解决了问题,我们程序员不⽤再去管理对象的创建了。

Spring:源码解读SpringIOC原理

Spring:源码解读SpringIOC原理

Spring:源码解读SpringIOC原理Spring IOC设计原理解析:本⽂乃学习整理参考⽽来(1) BeanFactory(2) BeanDefinition1、 XmlBeanFactory(屌丝IOC)的整个流程2、 FileSystemXmlApplicationContext 的IOC容器流程1、⾼富帅IOC解剖2、设置资源加载器和资源定位3、AbstractApplicationContext的refresh函数载⼊Bean定义过程:4、AbstractApplicationContext⼦类的refreshBeanFactory()⽅法:5、AbstractRefreshableApplicationContext⼦类的loadBeanDefinitions⽅法:6、AbstractBeanDefinitionReader读取Bean定义资源:7、资源加载器获取要读⼊的资源:8、XmlBeanDefinitionReader加载Bean定义资源:9、DocumentLoader将Bean定义资源转换为Document对象:10、XmlBeanDefinitionReader解析载⼊的Bean定义资源⽂件:11、DefaultBeanDefinitionDocumentReader对Bean定义的Document对象解析:12、BeanDefinitionParserDelegate解析Bean定义资源⽂件中的<Bean>元素:13、BeanDefinitionParserDelegate解析<property>元素:14、解析<property>元素的⼦元素:15、解析<list>⼦元素:16、解析过后的BeanDefinition在IoC容器中的注册:17、DefaultListableBeanFactory向IoC容器注册解析后的BeanDefinition:总结:1、依赖注⼊发⽣的时间2、AbstractBeanFactory通过getBean向IoC容器获取被管理的Bean:3、AbstractAutowireCapableBeanFactory创建Bean实例对象:4、createBeanInstance⽅法创建Bean的java实例对象:5、SimpleInstantiationStrategy类使⽤默认的⽆参构造⽅法创建Bean实例化对象:6、populateBean⽅法对Bean属性的依赖注⼊:7、BeanDefinitionValueResolver解析属性值:8、BeanWrapperImpl对Bean属性的依赖注⼊:1、介绍2、Spring IoC容器的lazy-init属性实现预实例化:(1) .refresh()(2).finishBeanFactoryInitialization处理预实例化Bean:(3) .DefaultListableBeanFactory对配置lazy-init属性单态Bean的预实例化:3、FactoryBean的实现:(1).FactoryBean的源码如下:(2). AbstractBeanFactory的getBean⽅法调⽤FactoryBean:(3)、AbstractBeanFactory⽣产Bean实例对象:(4).⼯⼚Bean的实现类getObject⽅法创建Bean实例对象:4.BeanPostProcessor后置处理器的实现:(1).BeanPostProcessor的源码如下:(2).AbstractAutowireCapableBeanFactory类对容器⽣成的Bean添加后置处理器:(3).initializeBean⽅法为容器产⽣的Bean实例对象添加BeanPostProcessor后置处理器:(4).AdvisorAdapterRegistrationManager在Bean对象初始化后注册通知适配器:5.Spring IoC容器autowiring实现原理:(1). AbstractAutoWireCapableBeanFactory对Bean实例进⾏属性依赖注⼊:(2).Spring IoC容器根据Bean名称或者类型进⾏autowiring⾃动依赖注⼊:(3).DefaultSingletonBeanRegistry的registerDependentBean⽅法对属性注⼊:⼀、什么是Ioc/DI?IoC 容器:最主要是完成了完成对象的创建和依赖的管理注⼊等等。

spring的ioc和aop的原理

spring的ioc和aop的原理

spring的ioc和aop的原理
1、IOC原理
Ioc(Inversion of Control,控制反转)是spring框架中非常基础
的一个概念,主要是将原本在程序中主动创建对象的控制权交给IOC容器,让程序更加专注于业务逻辑的处理。

具体来说,就是在xml文件中配置各
个bean及其依赖关系,然后由spring的IOC容器来负责bean的生命周
期管理,包括实例化、注入、初始化等,实现bean的依赖解耦。

2、AOP原理
AOP(Aspect Oriented Programming,面向切面编程)主要是对横切
关注点(cross-cutting concern)进行抽离,把业务逻辑和系统服务进
行分离,用来解决程序代码重复问题、提高程序维护性,系统中可以插入
新代码来增强原有功能,例如事务控制、日志记录等,以提高程序的可扩
展性。

Spring AOP是在程序运行期间,动态地将某段代码切入到指定方
法指定位置运行的编程方式。

SpringIOC容器基本原理

SpringIOC容器基本原理

SpringIOC容器基本原理2.2.1 IOC容器的概念IOC容器就是具有依赖注⼊功能的容器,IOC容器负责实例化、定位、配置应⽤程序中的对象及建⽴这些对象间的依赖。

应⽤程序⽆需直接在代码中new相关的对象,应⽤程序由IOC容器进⾏组装。

在Spring中BeanFactory是IOC容器的实际代表者。

Spring IOC容器如何知道哪些是它管理的对象呢?这就需要配置⽂件,Spring IOC容器通过读取配置⽂件中的配置元数据,通过元数据对应⽤中的各个对象进⾏实例化及装配。

⼀般使⽤基于xml配置⽂件进⾏配置元数据,⽽且Spring与配置⽂件完全解耦的,可以使⽤其他任何可能的⽅式进⾏配置元数据,⽐如注解、基于java⽂件的、基于属性⽂件的配置都可以。

那Spring IOC容器管理的对象叫什么呢?2.2.2 Bean的概念由IOC容器管理的那些组成你应⽤程序的对象我们就叫它Bean, Bean就是由Spring容器初始化、装配及管理的对象,除此之外,bean就与应⽤程序中的其他对象没有什么区别了。

那IOC怎样确定如何实例化Bean、管理Bean之间的依赖关系以及管理Bean呢?这就需要配置元数据,在Spring中由BeanDefinition代表,后边会详细介绍,配置元数据指定如何实例化Bean、如何组装Bean等。

概念知道的差不多了,让我们来做个简单的例⼦。

2.2.3 开始Spring Hello World之旅1、准备需要的jar包核⼼jar包:从下载的spring-framework-3.0.5.RELEASE-with-docs.zip中dist⽬录查找如下jar包org.springframework.asm-3.0.5.RELEASE.jarorg.springframework.core-3.0.5.RELEASE.jarorg.springframework.beans-3.0.5.RELEASE.jarorg.springframework.context-3.0.5.RELEASE.jarorg.springframework.expression-3.0.5.RELEASE.jar依赖的jar包:从下载的spring-framework-3.0.5.RELEASE-dependencies.zip中查找如下依赖jar包.apache.log4j-1.2.15.jarmons.logging-1.1.1.jarmons.collections-3.2.1.jar2、创建标准Java⼯程:3、项⽬搭建好了,让我们来开发接⼝,此处我们只需实现打印“Hello World!”,所以我们定义⼀个“sayHello”接⼝,代码如下:package com.ljq.test;public interface HelloService {public void sayHello();}4、接⼝开发好了,让我们来通过实现接⼝来完成打印“Hello World!”功能;package com.ljq.test;public class HelloServiceImpl implements HelloService{public void sayHello(){System.out.println("Hello World!");}}5、接⼝和实现都开发好了,那如何使⽤Spring IOC容器来管理它们呢?这就需要配置⽂件,让IOC容器知道要管理哪些对象。

Spring的IOC实现原理

Spring的IOC实现原理

Spring的IOC实现原理什么是SpringIOCspring ioc指的是控制反转,IOC容器负责实例化、定位、配置应⽤程序中的对象及建⽴这些对象间的依赖。

交由Spring容器统⼀进⾏管理,从⽽实现松耦合“控制反转”,不是什么技术,⽽是⼀种设计思想。

在Java开发中,Ioc意味着将你设计好的对象交给容器控制,⽽不是传统的在你的对象内部直接控制。

如何理解好Ioc呢?理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些⽅⾯反转了”,那我们来深⼊分析⼀下:●谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进⾏创建对象,是程序主动去创建依赖对象;⽽IoC是有专门⼀个容器来创建这些对象,即由Ioc容器来控制对象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括⽐如⽂件等)。

●为何是反转,哪些⽅⾯反转了:有反转就有正转,传统应⽤程序是由我们⾃⼰在对象中主动控制去直接获取依赖对象,也就是正转;⽽反转则是由容器来帮忙创建及注⼊依赖对象;为何是反转?因为由容器帮我们查找及注⼊依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些⽅⾯反转了?依赖对象的获取被反转了。

IOC实现原理使⽤反射机制+XML技术理解了这些基本概念后,我们通过⼀个简单的⽰意图来简单描述⼀下整个流程,从⽰意图可以看出,当web容器启动的时候,spring的全局bean的管理器会去xml配置⽂件中扫描的包下⾯获取到所有的类,并根据你使⽤的注解,进⾏对应的封装,封装到全局的bean容器中进⾏管理,⼀旦容器初始化完毕,beanID以及bean实例化的类对象信息就全部存在了,现在我们需要在某个service⾥⾯调⽤另⼀个bean的某个⽅法的时候,我们只需要依赖注⼊进来另⼀个bean的Id即可,调⽤的时候,spring会去初始化完成的bean容器中获取即可,如果存在就把依赖的bean的类的实例化对象返回给你,你就可以调⽤依赖的bean的相关⽅法或属性等;下⾯通过实例代码来模拟⼀下整个IOC的原理和执⾏流程,1、demo结构如下,2、pom依赖⽂件,这⾥只需要spring的基本依赖即可,<properties><spring.version>5.1.2.RELEASE</spring.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.6.1</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.2</version></dependency></dependencies>3、⾸先我们⾃定义两个注解,我们知道在业务类中经常使⽤ @Service来标记这个类是bean管理的类,⽽@Autowired或者@Resource⽤于bean之间相互依赖使⽤,// ⾃定义注解 service 注⼊bean容器@Target({ ElementType.TYPE })@Retention(RetentionPolicy.RUNTIME)public @interface SelfService {}//模拟@Autowired注解@Target({ TYPE, FIELD, METHOD })@Retention(RUNTIME)public @interface SelfAutowired {}4、模拟spring的bean容器类,想必使⽤过spring框架在进⾏整合测试的时候,都使⽤到下⾯这段代码,这段代码的作⽤其实就是模拟在spring启动加载的时候,通过这个类去初始化⼀个bean 的容器管理类,所有的bean的信息解析和保存都会在这个类⾥⾯进⾏,下⾯我们写⼀个这样的类来还原⼀下这个过程,SelfPathXmlApplicationContext app = new SelfPathXmlApplicationContext("com.congge.service.impl");1⾃定义spring的bean容器类,/**⾃定义bean管理器@author asus*/public class SelfPathXmlApplicationContext {private String packageName;// 封装所有的bean容器private ConcurrentHashMap<String, Object> beans = null;/*** 该类被创建出来的时候加载* @param packageName* @throws Exception*/public SelfPathXmlApplicationContext(String packageName) throws Exception {beans = new ConcurrentHashMap<String, Object>();this.packageName = packageName;initBeans();initEntryField();}/*** 初始化bean的实例对象的所有属性* @throws Exception*/private void initEntryField() throws Exception {// 1.遍历所有的bean容器对象for (Entry<String, Object> entry : beans.entrySet()) {// 2.判断属性上⾯是否有加注解Object bean = entry.getValue();attriAssign(bean);}}/*** 根据beanId获取bean名称* @param beanId* @return* @throws Exception*/public Object getBean(String beanId) throws Exception {if (StringUtils.isEmpty(beanId)) {throw new Exception("beanId参数不能为空");}// 1.从spring容器获取beanObject object = beans.get(beanId);// attriAssign(object);return object;}/*** 获取扫描包下⾯的所有bean*/private void initBeans() throws Exception {// 1.使⽤java的反射机制扫包,[获取当前包下所有的类]List<Class<?>> classes = ClassParseUtil.getClasses(packageName);// 2、判断类上⾯是否存在注⼊的bean的注解ConcurrentHashMap<String, Object> classExisAnnotation = findClassExisAnnotation(classes);if (classExisAnnotation == null || classExisAnnotation.isEmpty()) {throw new Exception("该包下没有任何类加上注解");}}/*** 判断类上是否存在注⼊⾃定义的bean的注解* @param classes* @return* @throws Exception*/public ConcurrentHashMap<String, Object> findClassExisAnnotation(List<Class<?>> classes) throws Exception { for (Class<?> classInfo : classes) {// 判断类上是否有注解 [获取⾃定义的service注解]SelfService annotation = classInfo.getAnnotation(SelfService.class);if (annotation != null) {// 获取当前类的类名String className = classInfo.getSimpleName();String beanId = toLowerCaseFirstOne(className);Object newInstance = newInstance(classInfo);beans.put(beanId, newInstance);}}return beans;}// ⾸字母转⼩写public static String toLowerCaseFirstOne(String s) {if (Character.isLowerCase(s.charAt(0)))return s;elsereturn (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();}/*** 通过class名称获取类的实例化对象* @param classInfo* @return* @throws ClassNotFoundException* @throws InstantiationException* @throws IllegalAccessException*/public Object newInstance(Class<?> classInfo)throws ClassNotFoundException, InstantiationException, IllegalAccessException {return classInfo.newInstance();}/*** 依赖注⼊注解原理* @param object* @throws Exception*/public void attriAssign(Object object) throws Exception {// 1.使⽤反射机制,获取当前类的所有属性Class<? extends Object> classInfo = object.getClass();Field[] declaredFields = classInfo.getDeclaredFields();// 2.判断当前类属性是否存在注解for (Field field : declaredFields) {SelfAutowired extResource = field.getAnnotation(SelfAutowired.class);if (extResource != null) {// 获取属性名称String beanId = field.getName();Object bean = getBean(beanId);if (bean != null) {// 3.默认使⽤属性名称,查找bean容器对象 1参数当前对象 2参数给属性赋值field.setAccessible(true); // 允许访问私有属性field.set(object, bean);}}}}}当这个类被初始化的时候,通过构造函数⾥⾯的两个⽅法,通过外部传⼊指定的包名,解析该包下⾯的所有类和相关注解,其实现原理主要是使⽤了反射,通过⼀个⼯具类获取到了所有的类的实例化集合后,我们对这个集合进⾏遍历,具体的执⾏⽅法可以看findClassExisAnnotation 这个⽅法,在findClassExisAnnotation这个⽅法⾥⾯,可以看到,我们使⽤⾃定义的注解去到这个实例类对象去匹配,如果匹配到了相应的注解,就把这个bean封装到全局的集合中,这⾥使⽤了concurrentHashMap进⾏封装,这⼀步完成之后,包含了⾃定义注解[@Service]的相关类对象就存在了内存集合中了,如果在web容器启动完毕之后,使⽤⾃⼰的bean的时候就可以直接通过getBean这个⽅法去容器⾥⾯直接获取就可以了,通过这个⽅法就可以拿到当前beanId对应的类的实例化对象,可以使⽤⾥⾯的相关⽅法,但是到这⾥并没有完事啊,假如在我们某个标注了@Service的类⾥⾯有下⾯这样的注解,即依赖了其他的某个bean,⽐如,在我们的userService类⾥⾯依赖了orderService,就形成了所谓的依赖注⼊,同样,依赖注⼊也是通过上⾯相同的⽅式,在initBean()⽅法结束之后⽴即执⾏,我们来看看这个⽅法,在initEntryField()这个⽅法⾥,要做的事情就是遍历上述初始化好的所有bean,然后再去每个bean的实例对象中解析并封装属性相关的对应信息,下⾯看⼀下initEntryField()这个⽅法,通过这个⽅法,就可以将某个bean中依赖的其他bean信息进⾏封装,/*** 依赖注⼊注解实现原理* @param object* @throws Exception*/public void attriAssign(Object object) throws Exception {// 1.使⽤反射机制,获取当前类的所有属性Class<? extends Object> classInfo = object.getClass();Field[] declaredFields = classInfo.getDeclaredFields();// 2.判断当前类属性是否存在注解for (Field field : declaredFields) {SelfAutowired extResource = field.getAnnotation(SelfAutowired.class);if (extResource != null) {// 获取属性名称String beanId = field.getName();Object bean = getBean(beanId);if (bean != null) {// 3.默认使⽤属性名称,查找bean容器对象 1参数当前对象 2参数给属性赋值field.setAccessible(true); // 允许访问私有属性field.set(object, bean);}}}}最后我们写⼀个测试类来验证⼀下,直接运⾏下⾯的main函数,public class Test1 {public static void main(String[] args) throws Exception {SelfPathXmlApplicationContext app = new SelfPathXmlApplicationContext("com.congge.service.impl"); UserServiceImpl userServiceImpl = (UserServiceImpl) app.getBean("userServiceImpl");String result = userServiceImpl.add();System.out.println("获取到了orderService的执⾏结果是 : " + result);System.out.println("当前的bean的实例对象是: " + userServiceImpl);}}可以看到我们⾃定义的bean容器已经⽣效了。

Spring源码:IOC原理解析(一)

Spring源码:IOC原理解析(一)

Spring源码:IOC原理解析(⼀)版权声明:本⽂为博主原创⽂章,转载请注明出处,欢迎交流学习!IOC(Inversion of Control),即控制反转,意思是将对象的创建和依赖关系交给第三⽅容器处理,我们要⽤的时候告诉容器我们需要什么然后直接去拿就⾏了。

举个例⼦,我们有⼀个⼯⼚,它⽣产各种产品,当你需要某个产品,⽐如你需要⼀辆汽车,你就告诉⼯⼚你需要⼀辆汽车,⼯⼚就会直接返回给你⼀辆汽车,⽽不需要你⾃⼰通过付出劳动来得到这辆汽车,你也不⽤关⼼⼯⼚是如何⽣产这辆汽车。

对应到我们的程序中就是,IOC容器会帮我们创建和管理对象,当你告诉容器你需要某个对象时,容器会把这个对象返回给你,⽽不需要⾃⼰去new出⼀个对象来,对象的创建和管理会由容器⾃动进⾏,直接从容器中拿来⽤就可以了。

IOC可以说是Spring最核⼼的思想,它使我们的开发变得简单(对象之间的依赖关系可以通过配置⽂件或者注解来建⽴),对于这种优秀的设计思想,我们当然有必要研究⼀下它的底层实现原理。

⾸先我们来关注⼀个接⼝,源码如下:package org.springframework.beans.factory;import org.springframework.beans.BeansException;import org.springframework.core.ResolvableType;import ng.Nullable;/**** @author Rod Johnson* @author Juergen Hoeller* @author Chris Beams* @since 13 April 2001**/public interface BeanFactory {String FACTORY_BEAN_PREFIX = "&";Object getBean(String name) throws BeansException;<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;Object getBean(String name, Object... args) throws BeansException;<T> T getBean(Class<T> requiredType) throws BeansException;<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;boolean containsBean(String name);boolean isSingleton(String name) throws NoSuchBeanDefinitionException;boolean isPrototype(String name) throws NoSuchBeanDefinitionException;boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;@NullableClass<?> getType(String name) throws NoSuchBeanDefinitionException;String[] getAliases(String name);}这个接⼝便是spring核⼼的bean⼯⼚定义,它是IOC容器的顶层接⼝,spring中所有bean⼯⼚都直接或间接的继承或实现了这个接⼝。

简单实现Spring的IOC原理详解

简单实现Spring的IOC原理详解

简单实现Spring的IOC原理详解控制反转(InversionofControl,缩写为IoC)简单来说就是当⾃⼰需要⼀个对象的时候不需要⾃⼰⼿动去new⼀个,⽽是由其他容器来帮你提供;Spring⾥⾯就是IOC容器。

例如:在Spring⾥⾯经常需要在Service这个装配⼀个Dao,⼀般是使⽤@Autowired注解:类似如下public Class ServiceImpl{@AutowiredDao dao;public void getData(){dao.getData();}在这⾥未初始化Dao直接使⽤是会报出空指针异常的,那么在Spring⾥⾯的做法就是通过反射来将需要的类帮你加载进来。

下⾯是⼀个例⼦模拟了Spring的DI和IOC⾸先写两个注解模拟Spring的注解:Entity注解代表的是Spring的@Service@Target(ElementType.TYPE) // 类@Retention(RetentionPolicy.RUNTIME)public @interface Entity {}代表的是Spring⾥⾯的@Autowrid@Target(ElementType.FIELD) //描述⽅法的@Retention(RetentionPolicy.RUNTIME) // 仅运⾏时保留public @interface Resources {}当注解建⽴完成之后再建⽴两个类:Rain类代表的是需要从其他地⽅获取天⽓数据(数据库或者服务器)public class Rain {public void rain(){System.out.println("正在下⾬"); // 为了⽅便直接写了}}Weather类代表的是获取到的天⽓数据@Entitypublic class Weather {@ResourcesRain rain; // 这⾥在后⾯通过反射直接注⼊rainpublic void weather_rain() {rain.rain();}下⾯是通过反射来直接注⼊:⾸先遍历指定的包名:这⼀步先省略,⾸先是建⽴⼀个List模拟Spring的bean容器,即将已经装初始化好的带有Entity注解的类全部初始化public class Weather_reflec {List<Object> objectList ;// 模拟Spring容器public Weather_reflec() {objectList= new ArrayList<Object>();}// 在这⾥其实最好的做法是先找出带有注解的类,判断带有Entity注解再传⼊。

Spring控制反转(IOC:实现+原理)

Spring控制反转(IOC:实现+原理)

Spring控制反转(IOC:实现+原理)控制反转1.概述Spring有IOC和AOP两个核⼼。

其中IOC我们说的控制反转,也就是将创建对象并⽣命周期的管理过程交给Spring处理。

在开发中不再需要关注对象的创建和声明周期的管理,我们需要式由Spring框架提供,这个由Spring管理创建对象和⽣命周期的机制称为控制反转。

创建对象的权⼒转给框架,他帮我们创建,我们不再使⽤new关键⾃来创建对象。

2.原理创建过程在初始化⼀个Spring容器时,Spring会解析spring的配置⽂件(applicationContext.xml),从上到下解析到<bean id=””,class=””>时,根据标签中的class属性指定的类的全路径名找到该类并通过反射来创建该类的对象,并创建的对象存⼊到内置的Map容器中管理,其中存⼊map中的键是该标签中的id值,值是创建的对象。

获取对象过程当通过context.getBeans("id值")⽅法来从容器中获取对象时,根据id从内置的Map中寻找是否有匹配的键值,如果有返回对象,如果没有抛出异常。

提⽰:默认情况下,多次获取同⼀个id的bean对象得到的是同⼀个对象(默认情况下创建的对象是单例的,如果需要多例可以该标签中设置多例)。

如果使⽤⼀个类配置多个<bean>标签设置不同的id ,每个id都会在内置Map中有⼀个键值对,其中的值是这个类创建的不同的对象。

同⼀个<beans>标签下不允许配置多个同id的<标签>,如果配置会报错。

3.实现⾸先创建lib⽬录导⼊需要依赖的包并buildpath:这些包可以spring官⽹下载也可以其他远程仓库可以下载。

提⽰:我们这⾥只是⼊门使⽤这种导⼊⽅式,后⾯不需要这样导⼊,开发中直接maven来⾃动导⼊)依赖包导⼊后在指定包中创建⼀个Person类(为了使⽤创建对象)package com.test.spring;public class Person {public void say(String str) {System.out.println(str);}}然后在src⽬录下创建spring的配置⽂件applicationContext.xml。

SpringIOC和SpringAOP的实现原理(源码主线流程)

SpringIOC和SpringAOP的实现原理(源码主线流程)

SpringIOC和SpringAOP的实现原理(源码主线流程)写在前⾯正本⽂参考了《spring技术内幕》和spring 4.0.5源码。

本⽂只描述原理流程的主线部分,其他⽐如验证,缓存什么可以具体参考源码理解。

Spring IOC⼀、容器初始化容器的初始化⾸先是在对应的构造器中进⾏,在applicationContext的实现类构造器中,⾸先对参数路径中的${}进⾏了处理,⽤系统变量替换(setConfigLocations⽅法)然后调⽤refresh⽅法(这个就是最核⼼的容器初始化⽅法)。

1、Resource定位:在refresh⽅法中调⽤obtainFreshBeanFactory⽅法告诉⼦类刷新beanfactory(其中是调⽤refreshBeanFactory刷新后getBeanFactory获取刷新后的factory返回)。

在刷新过程refreshBeanFactory中如果factory已经有了要消除再新建factory,其中loadBeanDefinitions是加载bean定义的⽅法。

在loadBeanDefinitions⽅法中创建了BeanDefinitionReader的实现类调⽤其loadBeanDefinitions⽅法(这个⽅法是重载⽅法,参数有为Resource的也有为String路径的,getConfigResources⽅法(默认返回null,⼦类重写,如ClassPathXmlApplicationContext类)和getConfigLocations⽅法获得Resource集合和资源路径集合(⼀般⼀个为空,⼀般是将容器的参数path设定为configLocations,ClassPathXmlApplicationContext有⼀种构造器是不设定configLocations⽽是直接⽤参数path⽣成ClassPathResource集合设定为configResources)分别进⾏load,实际上以路径为参数的重载⽅法在定位完Resource也会调⽤以resource为参数的loadBeanDefinitions来解析载⼊BeanDefinition,这个是第⼆步在下⾯介绍)。

spring ioc原理

spring ioc原理

spring ioc原理
spring IOC(Inversion of Control)是一种控制控制反转的技术,它使开发人员可以以更轻松的方式编写代码,同时可以更快速地访问应用程序的组件。

Spring IOC是一种容器,它实现了一种控制反转的模式,它能够帮助我们把软件系统中的对象和依赖关系管理得更加合理。

Spring IOC的工作原理是,在软件系统中,由Spring IOC容器负责管理对象之间的依赖关系,当一个对象需要其他对象的某个服务时,它可以向Spring IOC容器申请,Spring IOC容器会把它们之间的依赖关系自动建立起来,这样就可以使得对象之间的耦合性降低,从而使得软件系统更加灵活、可扩展。

Spring IOC的好处有很多,首先,它可以让我们节省时间,因为它可以自动管理对象之间的依赖关系,而不用花时间来手动管理它们;其次,它可以让我们更加灵活,因为它可以把对象之间的依赖关系变得更加灵活,而不用担心它们之间的关系;最后,它可以让我们更加容易管理,因为它可以把对象之间的依赖关系集中到一个位置,从而减少管理的复杂性。

Spring IOC是一种非常有用的技术,它可以让我们更加容易地管理对象之间的依赖关系,从而使得软件系统更加灵活、可扩展。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

【黑马程序员】Spring的IOC原理1. IoC理论的背景我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑。

如果我们打开机械式手表的后盖,就会看到与上面类似的情形,各个齿轮分别带动时针、分针和秒针顺时针旋转,从而在表盘上产生正确的时间。

图1中描述的就是这样的一个齿轮组,它拥有多个独立的齿轮,这些齿轮相互啮合在一起,协同工作,共同完成某项任务。

我们可以看到,在这样的齿轮组中,如果有一个齿轮出了问题,就可能会影响到整个齿轮组的正常运转。

齿轮组中齿轮之间的啮合关系,与软件系统中对象之间的耦合关系非常相似。

对象之间的耦合关系是无法避免的,也是必要的,这是协同工作的基础。

现在,伴随着工业级应用的规模越来越庞大,对象之间的依赖关系也越来越复杂,经常会出现对象之间的多重依赖性关系,因此,架构师和设计师对于系统的分析和设计,将面临更大的挑战。

对象之间耦合度过高的系统,必然会出现牵一发而动全身的情形。

耦合关系不仅会出现在对象与对象之间,也会出现在软件系统的各模块之间,以及软件系统和硬件系统之间。

如何降低系统之间、模块之间和对象之间的耦合度,是软件工程永远追求的目标之一。

为了解决对象之间的耦合度过高的问题,软件专家Michael Mattson提出了IOC理论,用来实现对象之间的“解耦”,目前这个理论已经被成功地应用到实践当中,很多的J2EE项目均采用了IOC框架产品Spring。

2. 什么是控制反转(IoC)IOC是Inversion of Control的缩写,多数书籍翻译成“控制反转”,还有些书籍翻译成为“控制反向”或者“控制倒置”。

1996年,Michael Mattson在一篇有关探讨面向对象框架的文章中,首先提出了IOC 这个概念。

对于面向对象设计及编程的基本思想,前面我们已经讲了很多了,不再赘述,简单来说就是把复杂系统分解成相互合作的对象,这些对象类通过封装以后,内部实现对外部是透明的,从而降低了解决问题的复杂度,而且可以灵活地被重用和扩展。

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

无论是创建还是使用对象B,控制权都在自己手上。

通过前后的对比,我们不难看出来:对象A获得依赖对象B的过程,由主动行为变为了被动行为,控制权颠倒过来了,这就是“控制反转”这个名称的由来。

3. IOC的别名:依赖注入(DI)2004年,Martin Fowler探讨了同一个问题,既然IOC是控制反转,那么到底是“哪些方面的控制被反转了呢?”,经过详细地分析和论证后,他得出了答案:“获得依赖对象的过程被反转了”。

控制被反转之后,获得依赖对象的过程由自身管理变为了由IOC容器主动注入。

于是,他给“控制反转”取了一个更合适的名字叫做“依赖注入(Dependency Injection)”。

他的这个答案,实际上给出了实现IOC的方法:注入。

所谓依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。

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

我们举一个生活中的例子,来帮助理解依赖注入的过程。

大家对USB接口和USB 设备应该都很熟悉吧,USB为我们使用电脑提供了很大的方便,现在有很多的外部设备都支持USB接口。

现在,我们利用电脑主机和USB接口来实现一个任务:从外部USB设备读取一个文件。

电脑主机读取文件的时候,它一点也不会关心USB接口上连接的是什么外部设备,而且它确实也无须知道。

它的任务就是读取USB接口,挂接的外部设备只要符合USB接口标准即可。

所以,如果我给电脑主机连接上一个U盘,那么主机就从U盘上读取文件;如果我给电脑主机连接上一个外置硬盘,那么电脑主机就从外置硬盘上读取文件。

挂接外部设备的权力由我作主,即控制权归我,至于USB 接口挂接的是什么设备,电脑主机是决定不了,它只能被动的接受。

电脑主机需要外部设备的时候,根本不用它告诉我,我就会主动帮它挂上它想要的外部设备,你看我的服务是多么的到位。

这就是我们生活中常见的一个依赖注入的例子。

在这个过程中,我就起到了IOC容器的作用。

通过这个例子,依赖注入的思路已经非常清楚:当电脑主机读取文件的时候,我就把它所要依赖的外部设备,帮他挂接上。

整个外部设备注入的过程和一个被依赖的对象在系统运行时被注入另外一个对象内部的过程完全一样。

我们把依赖注入应用到软件系统中,再来描述一下这个过程:对象A依赖于对象B,当对象A需要用到对象B的时候,IOC容器就会立即创建一个对象B送给对象A。

IOC容器就是一个对象制造工厂,你需要什么,它会给你送去,你直接使用就行了,而再也不用去关心你所用的东西是如何制成的,也不用关心最后是怎么被销毁的,这一切全部由IOC容器包办。

在传统的实现中,由程序内部代码来控制组件之间的关系。

我们经常使用new关键字来实现两个组件之间关系的组合,这种实现方式会造成组件之间耦合。

IOC 很好地解决了该问题,它将实现组件间关系从程序内部提到外部容器,也就是说由容器在运行期将组件间的某种依赖关系动态注入组件中。

4. IOC为我们带来了什么好处我们还是从USB的例子说起,使用USB外部设备比使用内置硬盘,到底带来什么好处?第一、USB设备作为电脑主机的外部设备,在插入主机之前,与电脑主机没有任何的关系,只有被我们连接在一起之后,两者才发生联系,具有相关性。

所以,无论两者中的任何一方出现什么的问题,都不会影响另一方的运行。

这种特性体现在软件工程中,就是可维护性比较好,非常便于进行单元测试,便于调试程序和诊断故障。

代码中的每一个Class都可以单独测试,彼此之间互不影响,只要保证自身的功能无误即可,这就是组件之间低耦合或者无耦合带来的好处。

第二、USB设备和电脑主机的之间无关性,还带来了另外一个好处,生产USB设备的厂商和生产电脑主机的厂商完全可以是互不相干的人,各干各事,他们之间唯一需要遵守的就是USB接口标准。

这种特性体现在软件开发过程中,好处可是太大了。

每个开发团队的成员都只需要关心实现自身的业务逻辑,完全不用去关心其它的人工作进展,因为你的任务跟别人没有任何关系,你的任务可以单独测试,你的任务也不用依赖于别人的组件,再也不用扯不清责任了。

所以,在一个大中型项目中,团队成员分工明确、责任明晰,很容易将一个大的任务划分为细小的任务,开发效率和产品质量必将得到大幅度的提高。

第三、同一个USB外部设备可以插接到任何支持USB的设备,可以插接到电脑主机,也可以插接到DV机,USB外部设备可以被反复利用。

在软件工程中,这种特性就是可复用性好,我们可以把具有普遍性的常用组件独立出来,反复利用到项目中的其它部分,或者是其它项目,当然这也是面向对象的基本特征。

显然,IOC不仅更好地贯彻了这个原则,提高了模块的可复用性。

符合接口标准的实现,都可以插接到支持此标准的模块中。

第四、同USB外部设备一样,模块具有热插拔特性。

IOC生成对象的方式转为外置方式,也就是把对象生成放在配置文件里进行定义,这样,当我们更换一个实现子类将会变得很简单,只要修改配置文件就可以了,完全具有热插拨的特性。

以上几点好处,难道还不足以打动我们,让我们在项目开发过程中使用IOC框架吗?5. IOC容器的技术剖析IOC中最基本的技术就是“反射(Reflection)”编程,目前.Net C#、Java和PHP5等语言均支持,其中PHP5的技术书籍中,有时候也被翻译成“映射”。

有关反射的概念和用法,大家应该都很清楚,通俗来讲就是根据给出的类名(字符串方式)来动态地生成对象。

这种编程方式可以让对象在生成时才决定到底是哪一种对象。

反射的应用是很广泛的,很多的成熟的框架,比如象Java中的Hibernate、Spring 框架,.Net中NHibernate、框架都是把“反射”做为最基本的技术手段。

反射技术其实很早就出现了,但一直被忽略,没有被进一步的利用。

当时的反射编程方式相对于正常的对象生成方式要慢至少得10倍。

现在的反射技术经过改良优化,已经非常成熟,反射方式生成对象和通常对象生成方式,速度已经相差不大了,大约为1-2倍的差距。

我们可以把IOC容器的工作模式看做是工厂模式的升华,可以把IOC容器看作是一个工厂,这个工厂里要生产的对象都在配置文件中给出定义,然后利用编程语言的的反射编程,根据配置文件中给出的类名生成相应的对象。

从实现来看,IOC 是把以前在工厂方法里写死的对象生成代码,改变为由配置文件来定义,也就是把工厂和对象生成这两者独立分隔开来,目的就是提高灵活性和可维护性。

6. IOC容器的一些产品Sun ONE技术体系下的IOC容器有:轻量级的有Spring、Guice、Pico Container、Avalon、HiveMind;重量级的有EJB;不轻不重的有JBoss,Jdon等等。

Spring框架作为Java开发中SSH(Struts、Spring、Hibernate)三剑客之一,大中小项目中都有使用,非常成熟,应用广泛,EJB在关键性的工业级项目中也被使用,比如某些电信业务。

.Net技术体系下的IOC容器有:、Castle等等。

是从Java的Spring移植过来的IOC容器,Castle的IOC容器就是Windsor部分。

它们均是轻量级的框架,比较成熟,其中已经被逐渐应用于各种项目中。

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

第一、软件系统中由于引入了第三方IOC容器,生成对象的步骤变得有些复杂,本来是两者之间的事情,又凭空多出一道手续,所以,我们在刚开始使用IOC框架的时候,会感觉系统变得不太直观。

所以,引入了一个全新的框架,就会增加团队成员学习和认识的培训成本,并且在以后的运行维护中,还得让新加入者具备同样的知识体系。

第二、由于IOC容器生成对象是通过反射方式,在运行效率上有一定的损耗。

如果你要追求运行效率的话,就必须对此进行权衡。

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

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

我们大体可以得出这样的结论:一些工作量不大的项目或者产品,不太适合使用IOC框架产品。

相关文档
最新文档