对IOC的理解
讲到IOC,其实也就是涉及到三个概念,ioc容器,控制反转,依赖注入嘛,ioc容器就可以看作是一个map,里面存贮了各种对象,在项目启动时,加载bean的原料信息放入到map中。控制反转呢就是说一个对象A依赖对象B,再没有IOC容器之前我们需要去new它,而有了IOC容器之后,IOC容器会主动创建对象B注入到对象A需要的地方,也就是说对象A获得依赖对象B的过程由主动行为变为了被动行为控制权颠倒过来了。依赖注入就是将对象放入所需属性的地方的过程。
IOC主要解决了对象之间耦合的问题,比如说server层需要调用dao层时,传统的方式下,我们需要在server层new一个dao层对象出来,这样的话,当我修改了dao层实现类时,server层也需要做出相应的一个改变,这就会造成server层和dao层之间的一个强耦合。而使用IOC来进行对象的实例化时,我们只需要关注dao的接口,具体的实现交给IOC容器,在容器中进行切换,从而来解除强耦合的这么一个问题。
对AOP的理解
我们的系统由很多组件组成,每个组件都有其各自的核心业务逻辑,除此之外,还常有着额外的职责,比如说打印日志,这种额外的职责我们称为横切关注点,因为它们会跨越系统中的多个组件。
而我们的面向切面编程(AOP)允许将横切关注点,如日志、安全和事务管理,从业务逻辑中分离出来并封装成独立的切面。这些切面随后被注入到目标对象中,从而增强其功能,可以减少系统的重复代码和降低模块之间的耦合度。
其底层使用的核心是动态代理。
分为两种,一种是jdk动态代理,另一种是cglib代理。
AOP 原理
AOP 实现的核心是代理模式,其中动态代理是最常用的一种方式。在 Spring AOP 中,主要有两种代理方式:
- JDK 动态代理 :基于接口的代理。JDK 动态代理通过实现接口中声明的所有方法来创建代理对象。当代理对象的方法被调用时,实际会转发到一个调用处理器的 invoke 方法。
- CGLIB 动态代理:基于类的代理。如果被代理的目标对象没有实现任何接口,Spring AOP 会使用 CGLIB 创建一个被代理对象的子类。在子类中覆盖父类的方法,以此来实现方法拦截。
无论是 JDK 动态代理还是 CGLIB 代理,其核心思想都是在运行时创建目标类的代理对象,通过代理对象来执行切面逻辑,然后再调用实际目标对象的方法。
动态代理对比
- JDK 动态代理:
-
- 只能代理实现了接口的类。
- 使用 java.lang.reflect.Proxy 类和 java.lang.reflect.InvocationHandler 接口实现。
- 代理对象和目标对象实现相同的接口。
- CGLIB 动态代理:
-
- 可以代理未实现接口的类。
- 通过生成目标对象的子类来创建代理对象。
- 使用 net.sf.cglib.proxy.Enhancer 类和 net.sf.cglib.proxy.MethodInterceptor 接口实现。
- 因为是基于继承,所以不能代理 final 类和 final 方法。
以上是我在学习spring的过程中对IOC和AOP的一个理解,有不对的地方,大家多多指教