依赖注入(Dependency Injection)
简单来说,一般的java或者面向对象思想的程序的架构,大量使用了“组合”这一实现方式,也就是在一个对象内部持有了别的对象的引用,来实现多个对象的交互。这些引用一般由程序员控制。回想起我的五子棋,确实如此,最简单的方式就是持有引用。
但这会导致一个很明显的问题:代码耦合度过大,换句话说,本来该分成一块一块的代码,全部因为持有引用耦合在了一起。一个方法名字参数要修改,可能持有这个对象的所有地方的代码都需要修改。同时维护起来会很困难,错误由各个地方的引用导致,又随着引用的持有传播。再者违背了面向对象的思想,一个东西内部也许从逻辑上和某个对象无关,可是却为了方便持有了其引用。
Spring In Action里面写骑士类的例子很好。
那么解决方法是什么呢?那就是依赖一种注入关系,具体需要持有引用的时候“注入”一个引用。其实这一种思想也不是啥特别冷僻的东西。在构造器中传入引用赋值给一个实例变量也就是一种注入。不过这么做不好。因为会让问题复杂化。更理想的方式是通过xml文件装配它。
面向切面(Aspect Oriented Programming)
一些程序中,有的逻辑模块可能在多个地方都会被使用。比如日志,安全等。这会导致两个问题。
1,如果这类逻辑要修改,可能到处都要修改。2,你的代码会变得混乱,因为不仅要完成自己本来的功能,还要去写日志等等。
而面向切面是说:把这种逻辑模块定义为“切面”。在xml文件中定义这个切面,并且控制在切面时程序的行为,“写日志”或者“验证安全性”等等。
控制反转(Inversion of Control)
使用一个Spring容器通过依赖注入控制各个组件的耦合。也就是说你写好了组件,不需要你去自己控制他们的依赖关系,哪个类又持有哪个类的对象,哪个类里面又要声明一个对象,而是把他们都放到一个容器里面,容器替你做这个(把组件组合起来)。
有两种实现形式:Bean工厂,应用上下文。其中第一种过于低级。目前主要使用的是第二种。第二种直接理解就是通过xml文件控制组件的耦合关系。