IoC和DI

IoC - Inversion of Control

是技术思想,不是技术实现,描述java开发领域对象的创建和管理的问题。
传统开发方式:依赖某个对象时,new一个该对象。
IoC思想开发方式:不自己new对象,将创建和管理对象的权利交给IoC对象,需要使用某个对象的时候,问IoC容器要。
image.png
为什么叫控制反转?

  • 控制:对象的创建(实例化)的权利。
  • 反转:控制权交给外部环境(spring框架 / IoC容器)。

IoC解决对象之间的耦合问题。
image.png

IoC vs DI

描述的是同一件事情,但是角度不一样。
image.png
IoC是站在对象的角度,对象实例化及其管理的权利交给(反转给)了容器。
DI是站在容器的角度,容器会把对象依赖的其他对象注入(送进去),如A对象实例化过程中因为声明了一个B类型的属性,那么就需要容器把B对象注入给A。

AOP

Aspect Oriented Programming,面向切面编程。
OOP思想是垂直纵向的继承体系,可以解决大多代码重复问题,但不是全部,需要AOP思想。
image.png
在多个纵向(顺序)流程中出现的相同子流程代码,我们称之为横切逻辑代码。
使用场景:

  • 事务控制
  • 权限校验
  • 日志

AOP踢出横向抽取机制,将横切逻辑代码与业务逻辑代码分离。
image.png
不改变业务逻辑的情况下,把横切逻辑代码应用到原有的业务逻辑中,达到和原来一样的效果。

  • 切:横切逻辑,原有业务逻辑代码不动,只操作横切逻辑代码。
  • 面:横切逻辑代码影响多个方法,多个点构成面。

实现IoC和AOP

除了new以外,还有什么技术可以实例化对象?
使用反射:Class.forName("全限定类名");
可以把全限定类名配置在xml中。
利用反射技术,配合工厂模式生产对象。工厂模式是一种非常好的解耦合的方式。
因此最终方案为,实现一个工厂类,它能够:

  1. 读取解析xml,然后通过反射技术实例化对象;
  2. 给外部提供获取对象的接口方法。

**
数据库事务归根结底是Connection的事务:
提交事务:connection.commit();
回滚事务:connection.rollback();

贴一个ProxyFactory源码:

  1. package com.lagou.edu.factory;
  2. import com.lagou.edu.utils.TransactionManager;
  3. import net.sf.cglib.proxy.Enhancer;
  4. import net.sf.cglib.proxy.MethodInterceptor;
  5. import java.lang.reflect.Proxy;
  6. /**
  7. * @author 应癫
  8. *
  9. *
  10. * 代理对象工厂:生成代理对象的
  11. */
  12. public class ProxyFactory {
  13. private TransactionManager transactionManager;
  14. public void setTransactionManager(TransactionManager transactionManager) {
  15. this.transactionManager = transactionManager;
  16. }
  17. /**
  18. * Jdk动态代理
  19. *
  20. * @param obj 委托对象
  21. * @return 代理对象
  22. */
  23. public Object getJdkProxy(Object obj) {
  24. // 获取代理对象
  25. return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),
  26. (proxy, method, args) -> {
  27. Object result;
  28. try {
  29. // 开启事务(关闭事务的自动提交)
  30. transactionManager.beginTransaction();
  31. result = method.invoke(obj, args);
  32. // 提交事务
  33. transactionManager.commit();
  34. } catch (Exception e) {
  35. e.printStackTrace();
  36. // 回滚事务
  37. transactionManager.rollback();
  38. // 抛出异常便于上层servlet捕获
  39. throw e;
  40. }
  41. return result;
  42. });
  43. }
  44. /**
  45. * 使用cglib动态代理生成代理对象
  46. *
  47. * @param obj 委托对象
  48. * @return
  49. */
  50. public Object getCglibProxy(Object obj) {
  51. return Enhancer.create(obj.getClass(), (MethodInterceptor) (o, method, objects, methodProxy) -> {
  52. Object result;
  53. try {
  54. // 开启事务(关闭事务的自动提交)
  55. transactionManager.beginTransaction();
  56. result = method.invoke(obj, objects);
  57. // 提交事务
  58. transactionManager.commit();
  59. } catch (Exception e) {
  60. e.printStackTrace();
  61. // 回滚事务
  62. transactionManager.rollback();
  63. // 抛出异常便于上层servlet捕获
  64. throw e;
  65. }
  66. return result;
  67. });
  68. }
  69. }

相关