Spring的定义
对DI的初步理解
对AOP的初步理解
对DI的深入探究
对AOP的深入探究
Spring的事务管理
Spring MVC
首先,我们来看这样一个场景:有一个骑士,他要去完成寻找圣杯的任务。情景很简单,我们以往的做法是这样的:声明一个骑士类,再声明一个寻找圣杯的任务类,骑士类是依赖于任务类的,代码如下:
Public class XunZhaoShengBeiRenWu { public ShengBei zhiXing() { return new ShengBei(); } } Public class QiShi { private XunZhaoShengBeiRenWu renWu; public QiShi () { renWu = new XunZhaoShengBeiRenWu (); } public ShengBei ZhiXingRenWu () { return renWu. zhiXing (); } }
上面的代码是没有任何问题的,不过仔细一看就会发现其中有很多设计不合理的地方。比如,骑士类和寻找圣杯的任务类耦合太紧密,这将直接导致该代码的重用性不高,并且,在做单元测试的时候也会有问题,因为每个骑士都要自己去获得寻找圣杯的任务,这就导致在测试骑士类的时候间接的测试了寻找圣杯的任务类。
因此,问题就是模块之间耦合太高。一个很好的解耦的方法就是将具体的实现隐藏在接口下面。具体做法是:声明一个“RenWu”接口,让“XunZhaoShengBeiRenWu”来实现这个接口。
Public interface RenWu { public ShengBei zhiXing() ; }
修改原来的“XunZhaoShengBeiRenWu”类为:
Public class XunZhaoShengBeiRenWu implement RenWu { public ShengBei zhiXing() { return new ShengBei(); } }
同时,为了与“RenWu”接口兼容,将原“QiShi”类修改为:
Public class QiShi implement RenLei { private RenWu renWu; public QiShi () { renWu = new XunZhaoShengBeiRenWu (); } public ShengBei zhiXingRenWu () { return renWu. zhiXing (); } }
经过这样的一番修改之后,我们的设计确实是比以前的好了许多。不过这里还有一个问题,骑士仍然是只能执行寻找圣杯的任务,如果骑士要执行一个保护圣杯的任务的话,那就要修改原来的代码了。为了解决这个问题,我们终于引入了DI。下面,我们将骑士类再次修改成如下这样:
Public class QiShi implement RenLei { private RenWu renWu; public void setRenWu (RenWu renWu ) { this.renwu = renWu ; } public ShengBei zhiXingRenWu () { return renWu. zhiXing (); } }
看了上面的修改你会发现,这时的骑士不是自己主动的获得寻找圣杯的任务了,而是被动的通过set方法被注入进来。这时,如果骑士要执行保护圣杯的任务,我们只要定义一个实现了“任务”接口的“保护圣杯任务”的类,并将该类的实例通过set方法注入即可。
在spring中,我们是通过xml配置文件来实现对骑士类进行注入的,具体的细节后面会提到,配置文件如下:
<beans> <bean id="renWu" class="com.alibaba.XunZhaoShengBeiRenWu"/> <bean id="qiShi" class="com.alibaba.QiShi"> <property name="renWu" ref="renWu" /> </bean> </beans>
在Main方法中,装载该bean的方法如下:
ApplicationContext ctx = new ClassPathXmlApplicationContext("com/alibaba/qishi.xml"); QiShi qiShi = (QiShi) ctx.getBean("qiShi"); qiShi.zhiXingRenWu();