谈谈自己对Spring IOC 和 AOP理解
一.谈谈自己对IOC的理解
Spring提供了一个容器,把我们业务代码中需要的一些bean都管理起来,这个Spring容器负责管理这些bean的生命周期,同时保证被依赖的bean能够正确找到自己所属的bean,能够根据代码中的依赖关系正确的实例化一个bean。要是没有Spring容器,我们就需要自己去创建bean,同时设置bean所依赖的bean,Spring容器把这些事情从业务代码中剥
离出来,实现解耦。IOC其实就是控制反转,它所要解决的问题就是一个对象如何获取它所依赖的对象,这个问题包含两层含义:假如对象A依赖对象B,A在获取对象B的时候先要创建对象B,然后把对象B设置到A的某个属性,其实这就是两件事情,那么现在的问题就是这两件事情由谁来做的问题了,首先对象A完全可以自己做这两件事情,new一个对象B然后赋值给其中某个字段,IOC的理念是B的创建和设置都不用A亲自去做,由Spring容器来做,这样A从之前自己动手去做变成了让别人去做,自己享用,这样关于对象B的获取A就不用关心了,IOC保证A在使用B的时候,B是现成的,其实完全可以理解为IOC就是把对象创建以及获取的责任托管给Spring容器了,这是一种责任的托管,这样就会有很多创建对象并且赋值的代码从我们的业务逻辑中剥离出来,从而使得我们在编写业务逻辑的时候不用再写对象的创建以及对象复制,只要我们愿意把这两件事情交由Spring容器来做。
二.谈谈自己对AOP的理解
在IOC的基础上出现了AOP的编程理念,所谓AOP就是面向切面编程,我们在编写一些业务逻辑代码的时候,经常会出现一个共性的逻辑,为了避免把这些共性的逻辑和一些特性的逻辑耦合在一起,我们可以把这些共性的逻辑抽取出来,变成一个横切逻辑,AOP负责把这些横切逻辑织入到我们指定的一些地方去。AOP最终通过代理或者动态修改字节码的方式来执行我们的横切逻辑,默认情况下,要是类实现了接口,直接走JDK的动态代理,要是类没有实现接口,就基于ASM动态修改类的字节码。要是采用JDK的动态代理,这样每次生成的代理都会增加到perm区,占据一定的内存空间,同样我们需要注意一点,jdk每次生成的代理都会被增加上ACC_FINAL的标志,就是说生成的代理类是一个final类,这个类不允许被继承,也就不允许被再次代理。其实JDK的proxy之所以这么搞,我觉得是出于JVM层次的优化,首先,final类不允许被继承,这样final类中的方法就不会被重写,这样在调用的时候JVM就不会动态去寻找调用方法的地址,其次,我们想假设类A被代理成proxyA,要是proxyA再次被代理成proxyB的话,这时候proxyA其实在系统中已经没啥用了,但是proxyA在perm区还占据了一定内存空间,这会给JVM的GC带来负担。