前言 学习过Spring框架的人一定都会听过Spring的IOC(控制反转)这个概念,对于初学Spring的人来说,总觉得IOC是模糊不清的,是很难理解的,今天和大家分享网上的一些技术大牛们对Spring框架的IOC的理解以及谈谈我对SpringIOC的理解。IOC是什么 IOCInversionofControl,即控制反转,不是什么技术,而是一种设计思想。在Java开发中,IOC意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。如何理解好IOC呢?理解好IOC的关键是要明确谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了,那我们来深入分析一下: (1)谁控制谁,控制什么:传统JavaSE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建;谁控制谁?当然是IoC容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。 (2)为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。 用图例说明一下,传统程序设计如图,都是主动去创建相关对象然后再组合起来: 当有了IOC的容器后,在客户端类中不再主动去创建这些对象了,如图所示: 接下来我们说一下IOC的4个特性1。lazyInit延迟加载 Bean对象的延迟加载(延迟创建) ApplicationContext容器的默认为是在启动服务器时将所有singletonbean提前进实例化。提前实例化意味着作为初始化过程的部分,ApplicationContext实例会创建并配置所有的singletonbean。完整版Java面试题地址:JAVA后端面试题整合1。1XML方式开启延迟加载: lazyinit配置bean对象的延迟加载,true或者falsefalse就是立即加载beanidlazyResultclasscom。lagou。edu。pojo。Resultlazyinitfalsebean复制代码复制代码 我们先来看一下当lazyinitfalse也就是立即加载的时候: 可以看到,在容器启动后,getBean之前,lazyResult这个bean已经存在了。 然后我们把lazyinittrue,设置为true 然后我们F8往下走一步: 发现出现了lazyResult1。2注解开启延迟加载: Lazy: 1。3全局配置defaultlazyinit: 在bean的根标签中: 应用场景:(1)开启延迟加载定程度提容器启动和运转性能(2)对于不常使的Bean设置延迟加载,这样偶尔使的时候再加载,不必要从开始该Bean就占资源2。FactoryBean和BeanFactory2。1BeanFactory 容器的顶级接口,定义了容器的一些基础行为,负责生产和管理Bean的一个工厂,具体使用它下面的子接口类型,比如ApplicationContext2。2FactoryBean spring中的bean有两种 普通bean 工厂bean(FactoryBean)可以生产某一个类型的bean实例(返回给我们),也就是说我们可以借助于它自定义bean的创建过程。 Bean创建的三种式中的静态法和实例化法和FactoryBean作类似,FactoryBean使较多,尤其在Spring框架些组件中会使,还有其他框架和Spring框架整合时使可以让我们自定义Bean的创建过程,完成复杂bean定义publicinterfaceFactoryBeanT{返回FactoryBean创建的实例,如果isSingleton返回true,则该实例会放到Spring容器的单例缓存池中MapNullableTgetObject()throwsException;返回FactoryBean创建的bean类型NullableClasslt;?getObjectType();返回作用域是否单例defaultbooleanisSingleton(){returntrue;}}复制代码复制代码2。2。1新建类CompanyFactoryBean,实现FactoryBean接口,并重写方法:publicclassCompanyFactoryBeanimplementsFactoryBeanCompany{privateStringcompanyInfo;注入公司名称,地址,规模以逗号分隔publicvoidsetCompanyInfo(StringcompanyInfo){this。companyInfocompanyInfo;}OverridepublicCompanygetObject()throwsException{创建复杂对象CompanyCompanycompanynewCompany();String〔〕splitcompanyInfo。split(,);company。setName(split〔0〕);company。setAddress(split〔1〕);company。setScale(Integer。parseInt(split〔2〕));returncompany;}OverridepublicClasslt;?getObjectType(){返回bean的类型returnCompany。class;}OverridepublicbooleanisSingleton(){是否是单例returntrue;}}复制代码复制代码publicclassCompany{privateStringname;privateStringaddress;privateintscale;省略getset和toString}复制代码复制代码2。2。2xml文件中配置beanbeanidcompanyBeanclasscom。lagou。edu。factory。CompanyFactoryBeanpropertynamecompanyInfovalue拉钩,中关村,500propertybean复制代码复制代码2。2。3测试org。junit。Testpublicvoidtest(){ApplicationContextapplicationContextnewClassPathXmlApplicationContext(applicationContext。xml);ObjectcompanyBeanapplicationContext。getBean(companyBean);System。out。println(companyBean);}结果返回的是Company{name拉钩,address中关村,scale500}复制代码复制代码 虽然在xml配置文件中配置的bean的classcom。lagou。edu。factory。CompanyFactoryBean但是返回的Company类型。 如何返回CompanyFactoryBean类型呢? 3。后置处理器 Spring提供了两种后处理bean的扩展接,分别为BeanPostProcessor和BeanFactoryPostProcessor,两者在使上是有所区别的。 初始化(BeanFactory)Bean对象 在BeanFactory初始化之后可以使BeanFactoryPostProcessor进后置处理做些事情 在Bean对象实例化(并不是Bean的整个命周期完成)之后可以使BeanPostProcessor进后置处理做些事情 注意:对象不定是springbean,springbean定是个对象3。1SpringBean生命周期图 按照上述描述的打印一下。看看是否一致:实现了BeanNameAware、BeanFactoryAware、ApplicationContextAware、InitializingBean,DisposableBean接口publicclassResultimplementsBeanNameAware,BeanFactoryAware,ApplicationContextAware,InitializingBean,DisposableBean{privateStringstatus;privateStringmessage;省略getsettoString方法OverridepublicvoidsetBeanFactory(BeanFactorybeanFactory)throwsBeansException{System。out。println(4。BeanFactoryAware:beanFactory);}OverridepublicvoidsetBeanName(Stringname){System。out。println(3。BeanNameAware:name);}OverridepublicvoidsetApplicationContext(ApplicationContextapplicationContext)throwsBeansException{System。out。println(5。ApplicationContextAware:applicationContext);}OverridepublicvoidafterPropertiesSet()throwsException{System。out。println(7。InitializingBean);}publicvoidinitMethodTest(){System。out。println(8。initMethod);}PostConstructpublicvoidpostCoustrcut(){System。out。println(postCoustrcut);}销毁之前执行PreDestroypublicvoidpreDestroy(){System。out。println(销毁之前执行);}Overridepublicvoiddestroy()throwsException{System。out。println(DisposableBean);}}复制代码复制代码拦截实例化之后的对象(实例化了并且属性注入了)拦截所有的ComponentpublicclassMyBeanPostProcessorimplementsBeanPostProcessor{OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName)throwsBeansException{if(lazyResult。equalsIgnoreCase(beanName)){System。out。println(MyBeanPostProcessorbefore);}returnbean;}OverridepublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName)throwsBeansException{if(lazyResult。equalsIgnoreCase(beanName)){System。out。println(MyBeanPostProcessorAfter);}returnbean;}}复制代码复制代码XML配置文件中:beanidlazyResultclasscom。lagou。edu。pojo。ResultinitmethodinitMethodTestbean复制代码复制代码测试:org。junit。TestpublicvoidtestBeanLazy(){ClassPathXmlApplicationContextapplicationContextnewClassPathXmlApplicationContext(classpath:applicationContext。xml);ObjectlazyResultapplicationContext。getBean(lazyResult);System。out。println(lazyResult);applicationContext。close();}复制代码复制代码 打印出: 4。其他: 资料获取方式:关注小编转发文章私信【857】获取上述资料 重要的事情说三遍,转发转发转发,一定要记得点赞转发哦!!!