原始写法存在的问题
这里的原始写法指的是不使用IOC和AOP之前代码存在的问题(以转账问题来说明):
- 强耦合,也就是说 new 关键字将接口的实现类相耦合,不符合面向接口开发的最优原则。简单的说就是没有IOC之前,我们的依赖关系就要体现在类的 new 对象中,并且要有具体的实现,两个实现类相耦合就属于强耦合,应面向接口编程,而非实现。属于IOC的问题。
- 针对具体的业务来说,事务控制很重要,否则会出现数据错乱等问题,这个控制属于AOP层面的问题。
解决
针对问题一
- 我们直接使用 new 来创建对象,在Java中,我们还可以使用反射来创建对象。反射需要的内容就是类的全限定类名。
- 使用工厂模式来通过反射技术来生产对象,工厂模式是解耦合非常好的一种方式。
简单的来说就是在工厂中通过反射来生产/实例化对象。
实现
IOC实现
针对于第一个来说,我们需要做的就是创建工厂来生产对象,实现流程如下:
如何解决上面的硬编码问题呢?其实还是利用反射,这里如何做的,想想其实就是给成员变量赋值的问题,如何给成员变量赋值,无非就是两种方式:
- set方法
- 构造方法
有那种味道了,这不就是 set 注入和 构造器注入嘛。我们在 xml 文件的bean标签中配置 property 属性来配置成员变量,两个属性,一个是name,一个是ref,name表示属性名,ref表是bean的id,这样我们在解析xml的时候就需要多做一个操作,用来解析成员变量,来调用上面两种方式中的一种来设置属性值。
上面就是整个IOC的实现了。
AOP实现
使用事务控制来说明AOP的实现,首先我们在业务逻辑中肯定会有多个进行数据库的操作,这个时候如果我们不进行控制,那么每一个操作就是用一个连接,在执行完成之后就会关闭,这种情况下无论如何都做不到一个service中的事务控制,所以我们要做的第一步就是将 连接与当前线程进行绑定。
连接与线程绑定之后我们就可以保证在一个方法中,只使用一个连接对象,我们就可以进行事务控制,事务控制的代码我们进行单独的封装,提供的操作有三个:开启事务,也就是将自动提交关闭;事务提交;事务回滚。这就是我们封装的事务处理器需要做的事情。
最后就是将事务插入到service的执行中去做事务控制,那这个就是关键了,也就是我们所说的横切代码与业务代码进行分期,这个操作就需要依靠动态代理来实现,动态代理可以做到方法的增强,这就是AOP的实现。
整个流程其实最后一步才是真正AOP的实现,本质其实就是动态代理。