IOC / AOP
IOC/AOP
标签(空格分隔): Spring
什么是IoC
借助"第三方" 实现具有依赖关系的对象之间的解耦.
将各个对象类封装之后, 通过IoC容器来关联这些对象类, 这样对象和对象之间就通过IoC容器进行联系, 但对象和对象之间并没有什么直接联系. 这样就做到了具有依赖关系的对象之间的解耦.
为何称为控制反转
软件系统在没有引入IoC容器之前, 对象A依赖对象B, 那么对象A在实例化或者运行到某一点的时候, 就必须主动创建对象B或者使用已经创建好的对象B, 其中不管是创建还是使用已经创建的对象B, 控制权都在我们自己的受伤.
如果软件系统引入IoC容器之后, 对象A和对象B就失去了直接联系, 所以对象A实例化运行之后, 如果需要对象B的话, IoC容器就会主动去创建一个对象B交给对象A去使用.
通过对比可以看到对象A依赖对象B的过程由主动且需要我们手动创建的过程, 变成被动且不需要我们多加注意的过程. 将对象交给了IoC容器处理, 控制权颠倒过来, 这就是控制反转.
依赖注入DI
所谓依赖注入,就是由IoC容器在运行期间, 动态的将某种依赖关系注入到对象之中.
依赖注入和控制反转是从不同的角度描述同一件事情, 就是指通过引入IoC容器, 利用依赖注入的方式, 实现对象之间的解耦.
优点
IoC生成对象的方式转为外置方式, 也就是把对象生成放在配置文件里进行定义, 这样, 当我们更滑一个实现子类将会变的很简单, 只需要修改配置文件就可以了, 具有可以热插拔的特性.
可维护性比较好, 非常便于进行单元测试, 便于调试程序和诊断故障.
缺点
软件系统中由于引入了IoC容器, 生成对象的步骤变得复杂, 本来是两者之间的关系, 这样就变成了三者, 在刚刚使用IoC框架的时候, 会感觉系统变得不太直观.
由于IoC容器生成对象的方式是通过反射, 在运行效率上有一定的额损耗.
什么是AOP
Spring AOP面向切面编程, 将日志, 事务等相对独立且重复的功能抽取出来, 利用Spring的配置文件或者注解的形式将这些功能织入进去, 提高复用性.
Spring IoC 如何实现
Bean工厂(
com.springframework.beans.factory.BeanFactory
): 是Spring框架中最核心的接口, 它提供了高级IoC的配置机制. BeanFactory使管理不同类型的Java对象成为可能.
应用上下文(
com.springframework.context.ApplicationContext
):建立在BeanFactory
基础之上提供了更多面向引用的功能, 它提供了国际化支持和框架事件体系, 更加易于创建实际应用.
我们一般称BeanFactory
为IoC
容器, 而称ApplicationContext
为应用上下文或者Spring容器.
BeanFactory是Spring框架的基础设置, 面向Spring本身; ApplicationContext面向使用Spring框架的开发者, 几乎所有的应用场合都可以直接使用ApplicationContext
.
Spring框架是工厂, 而被创建的类对象本身也可能是一个工厂, 这就形成了创建工厂的工厂.
Spring AOP
有了IOC其中CGLIB
解决了静态代理和动态代理对类的接口的依赖性和功能依赖性的问题之后, 使得将所有类(非final修饰的类)都实现代理模式成为可能(CHLIB是基于继承的方式做的动态代理). 所以IOC是AOP的基础.
面向切面编程, 在我们的应用中, 经常需要做一些事情, 但是这些事情与核心业务无关, 比如要记录所有update的执行时间, 操作人信息等等 到日志. 通过 AOP就可以在不修改原有代码的情况下完成需求.
AOP思想: 基于动态代理把各个事务单独抽取出来, 然后通过配置去寻找他的前置,后置,异常等方法.
实际上就是通过 [动态代理设计模式][1]的动态代理方法, 使用 InvocationHandler传入类加载器和实现的接口 以 获取代理运行的被代理类的函数的方法名和传入的参数, 然后通过反射创建被代理类完成其功能, 并在其前和其后加入其它功能.
JDK动态代理类和委托类需要实现同一个接口, 也就是说只有实现了某个接口的类可以使用Java动态代理机制. 但是, 事实上使用中并不是遇到的所有类都会有实现接口. 因此, 对于没有实现接口的类, 就不能使用该机制. CGLIB则可以实现对类的动态代理.