首先我们在熟悉不过的就是OOP面向对象编程了,面向对象编程专注于完成一个模块内部的功能,而不会去关心其他模块的功能。那么为什么会出现面向切面编程呢?当然是有用的,AOP主要是为了将与业务逻辑无关的代码分离开来,比如:日志,权限,事务处理,异常处理,性能统计。这样就可以大大的减少重复代码的编写,想想在每一个业务模块都单独写输出日志的代码多麻烦。
(图片盗的,水印都没去掉O(∩_∩)O~)
从图中可以看到,三条红线就代表着面向切面的三个类,他们与业务逻辑无关,而且是插拔式的,与黑色横线没有耦合,想想都很美好(就好比没有藕断丝连的美好爱情)。比如在service层中我们可能会用到日志的记录和权限的判断,那我们就可以将service作为切点,在我们的切面类中添加上通知,定义通知的类型,用来决定什么时候执行这个方法。
代码的具体实现就不讲了,主要以原理为主,等我自己的代码仓库能够见人的时候再放出来哈。
<!-- 定义自动代理 --> <aop:aspectj-autoproxy /> <!-- 将程序中的交叉业务逻辑(比如安全,日志,事务等),封装成一个切面,然后注入到目标对象(具体业务逻辑)中去。 --> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.xl.service..*.*(..))" /> </aop:config>
然后再讲一下控制反转(Ioc)和依赖注入(DI),就只听这名字也能发现控制反转应该比依赖注入好理解多了,初学者面对依赖注入这四个字真的懵逼啊(至少我刚听到这名词的时候很懵)。这两的区别如下:
控制反转:创建对象实例的控制权从代码控制剥离到IOC容器控制,实际就是你在xml文件控制,侧重于原理。 依赖注入:创建对象实例时,为这个对象注入属性值或其它对象实例,侧重于实现。
既然两者只是原理和实现的区别,所以只了解控制反转什么意思就知道依赖注入是什么意思了。控制反转?就听这名字,好像还挺有意思的。。。举个栗子吧,我们找对象,会有一个我们类,然后会有一个对象类,我们类面有个属性就是对象类,我们要找对象,就需要先new一个对象类,然后再用set方法set对象类,这样就相当于牵手成功了。可以看出我们类依赖于对象类,并且需要主动去new一个对象类。这时候出现了一个婚介所,我们不再需要主动去找对象了,婚介所直接给我们进行介绍,我们类上直接来个注解:我想找对象,然后就可以直接获取婚介所推送的对象类了。好吧,我承认我举得这个例子真的不咋样(手动滑稽)。
用一句话就能记住控制反转的意思了:控制反转就是获取依赖对象(或文件)的方式反转了,以前是主动找,现在是Ioc容器直接给你分配。
上一篇提到了解耦的问题,这里可以显而易见的看出AOP实现了局部解耦,但是Ioc也实现了解耦,这个可能小伙伴们会有所疑问。不就是多了个中介吗,怎么就解耦了呢(减少对外部的依赖了呢)。
看完这句话就知道了:
解耦的本质就是将类之间的直接关系转换成间接关系,不管是类向上转型,接口回调还是适配器模式都是在类之间加了一层,将原来的直接关系变成间接关系,使得两类对中间层是强耦合,两类之间变成弱耦合关系。
至于理解间接关系实现了解耦,我个人的理解是这样的:自己主动去找房子,耦合度巨高,毕竟亲力亲为。现在直接把需求挂到中介上了,中介会给我推a房子还是b房子都由中介说了算了,这样我和房子之间的关系就没有那么强的依赖了。