本文将从以下几个问题来讲解IoC&AOP:什么是IoC?IoC解决什么问题?IoC和DI的区别?什么是AOP?AOP解决什么问题?为什么AOP叫Aspect编程?首先申明:IoC&AOP不是Spring提出来的。它们其实在Spring之前就已经存在了,只是那时候比较理论化。Spring在技术层面很好的实现了这两个思想。什么是IoCIoC(Inversionofcontrol)InversionofControl/控制反转。这是一个想法,而不是技术实现。描述:Java开发领域对象的创建和管理。例如:现有的A类依赖B类的传统开发方式:往往是手动使用new关键字在A类中新建一个B的对象。使用IoC思想的开发方式:不使用new关键字来创建对象,但是它是通过IoC容器(Spring框架)来帮助我们实例化对象的。我们需要哪个对象可以直接从IoC容器传过来。从以上两种开发方式的对比来看:我们“失去了一个权力”(创建和管理对象的权力),从而获得了一个好处(不需要考虑对象的创建、管理等)为什么叫Inversionofcontrol控制:指对象创建(实例化、管理)中的权力倒置:控制权交给外部环境(Spring框架、IoC容器)IoC解决什么问题?IoC的思想是双方互不依赖,相关资源由第三方容器管理。这样做有什么好处?对象之间的耦合度或依赖度降低;资源变得更容易管理;例如,如果使用Spring容器,则可以轻松实现单例。比如:有一个User的操作,是使用Service和Dao的二层结构开发的。Service层如果想在不使用IoC思想的情况下使用Dao层的具体实现,需要在UserServiceImpl中通过new关键字手动new创建IUserDao的具体实现类UserDaoImpl(不能直接新建接口类)。很完美,这个方法也是可以实现的,但是我们想象一下这样一个场景:在开发过程中突然接到一个新的需求,针对IUserDao接口又开发了一个具体的实现类。因为Server层依赖于IUserDao的具体实现,所以我们需要修改UserServiceImpl中的新对象。如果只有一个类引用了IUserDao的具体实现,你可能觉得还可以,修改起来也不是很费力,但是如果有很多地方引用了IUserDao的具体实现,一旦IUserDao的实现需要要被替换掉,那么修改起来就很头疼了。利用IoC的思想,我们将对象的控制权(创建和管理)交给IoC容器来管理。我们在使用的时候,可以直接向IoC容器“询问”IoC和DI。InverseofControl:控制反转)是一种设计思想或某种模式。这种设计思路是将程序中手动创建对象的控制权交给Spring框架来管理。IoC在其他语言中也有应用,并不是Spring特有的。IoC容器是Spring用来实现IoC的载体。IoC容器其实就是一个Map(key,value),Map中存放着各种对象。IoC最常见、最合理的实现称为依赖注入(DependencyInjection,简称DI)。而且,MartinFowler在一篇文章中提到IoC更名为DI,原文如下,原文地址:https://martinfowler.com/articles/injection.html。老马的大意是说IoC太普通了,表达能力太强,很多人会被搞糊涂。因此,最好使用DI来准确命名此模式。什么是AOPAOP:Aspectorientedprogramming面向切面编程,AOP是OOP(面向对象编程)的延续。让我们先来看一个OOP的例子。例如:有Horse、Pig、Dog三个类,这三个类中有两个方法eat和run。通过OOP思想中的继承,我们可以提取出一个Animal的父类,然后将eat和run方法放到父类中。Horse、Pig、Dog都可以通过继承Animal类自动获得eat()和run()方法。这样会减少很多重复的代码。OOP编程思想可以解决大部分的代码重复问题。但也有一些问题无法处理。比如父类Animal中多个方法的同一个位置出现重复代码,OOP无法解决。/***动物父类*/publicclassAnimal{/**Height*/privateStringheight;/**Weight*/privatedoubleweight;publicvoideat(){//性能监控代码longstart=System.currentTimeMillis();//业务逻辑代码System.out.println("Icaneat...");//性能监控代码System.out.println("执行时间:"+(System.currentTimeMillis()-start)/1000f+"s");}publicvoidrun(){//性能监控代码longstart=System.currentTimeMillis();//业务逻辑代码System.out.println("Icanrun...");//性能监控代码System.out.println("执行时间:"+(System.currentTimeMillis()-start)/1000f+"s");}}这部分重复的代码一般称为横切逻辑代码。横切逻辑代码的问题:代码重复。横切逻辑代码和业务代码混合在一起。代码很臃肿。AOP就是用来解决这些问题的。业务逻辑代码分离代码拆分相对容易,难点在于如何在不改变原有业务逻辑的情况下,悄悄地将横向逻辑代码应用到原有业务逻辑中,从而达到和之前一样的效果。AOP解决什么问题?从上面的分析我们可以发现,AOP主要用来解决:在不改变原有业务逻辑的情况下,增强横切逻辑代码,从根本上解耦,避免横切逻辑代码重复。为什么AOP叫面向切面编程?它指的是横切逻辑。原有业务逻辑代码不动,只能操作横切逻辑代码。因此,对于横切逻辑平面:横切逻辑代码往往会影响很多方法,每个方法就像一个点,多个点组成一个面。这里有一个面条的概念作者:导哥链接:https://juejin.im/post/5ecf62ee51882542ef4f851f来源:掘金
