我们常写的代码,业务层Service层需要用到Dao层的实例,就会在Service层中,new一个Dao的实例。spring可以看成一个工厂,我们可以配置一个DaoFactory,从工厂中取出一个dao的实例即可。通过工厂模式,获取各个组件。再后来,就有了spring容器,将所有的bean进行配置,然后spring内部会通过反射机制会创建这些bean对应的对象。之后,会给对象进行注入。比如:UserService中有个UserDao,它会将UserDao注入进去。这就是所说的依赖注入DI。
所有的对象都是由spring容器创建,并放在spring容器中进行管理,这就是控制反转IOC。
以前,需要在controller层中,UserService service = new UserService();现在不需要,只需要在spring中配置一下,spring就会自动创建。这样呢,我问的Controller层、Service层、Dao层都不需要我们自己new,都交给spring容器去,而且,Controller层需要Service的实例,Service层需要Dao的实例,spring会自动注入的。
IoC和DI由什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”。
AOP是面向切面编程,它的起源是来自一种代理模式。什么叫做代理呢?比如我们要上百度,我们会先到代理服务器上,代理服务器再去找百度。我们要UserService类,通常会先去找其代理类,因为代理类的功能要比类本省的功能更强大。这只是一个类,如果有一组类,那我们是不是要写一组的代理类呀?这显然是很笨的方法,后来就有了动态代理,jdk的动态代理,它有个缺点,就是必须要面向接口,如果一个类没有接口,那通过jdk的动态代理也完不成其功能,然后又有了cglib,即使没有接口,它也能搞出一个动态代理。
有了这个呢,我们就想有没有这个框架,可以将一组XXXService类产生动态代理类,这时候就需要通过AOP了。比如我们要增强一组类中的save方法,记录日志。这时候,就需要AOP面向切面编程,具体是哪一个方法呢,这就是切面。哪一个类,它的包、方法名等是什么样的,统统给这样的进行统一的增强。比如,以save(或update或delete等)开头的方法,我们可以定义一个增强类,比如存放日志的类,我们就可以把这个类切到(纵向),该方法上边去,那这个方法就有了记录日志的功能了。这样,我们可以在调用方法之前增强,方法之后增强,而且是一组类中,而不是一个类。这样就可以对Service类中的所有的方法起作用了,这就是切面编程。
AOP应用场景
最常用的就是事务管理。就是一些非查询的操作(如转账),这种就需要在方法调用前开启事务,在方法结束后关闭事务,在方法抛出异常后,回滚事务。这时候就需要spring的AOP了。这时候就需要一个切面,就这些事务管理切进去(纵向),那它就有了开启事务、关闭事务、回滚事务的功能了。是AOP的一个应用。
还有就是日志功能,以前每个方法try catch,catch中都会记录日志,假如100个方法中都有这种代码,那岂不是要写很多次吗?这时候就需要AOP去处理,可以通过切面(包含所有的方法),我们就在抛出异常时候,将代码切入方法中,这样就可以实现所有的方法都有日志功能。(个人观点,如有理解错误的地方,可以相互讨论。

拦截器,它也是具有切面编程的思想,只不过是特殊的切面。