眾所周知,Spring是提倡基于接口編程的。
但有些Manager類,比如SaleOrderManager ,只有5%的機(jī)會(huì)再有另一個(gè)Impl實(shí)現(xiàn)。95%時(shí)間里這兩兄弟站一起,就像C++里的.h和.cpp,徒增維護(hù)的繁瑣(經(jīng)常要同步兩個(gè)文件的函數(shù)聲明),和代碼瀏覽跳轉(zhuǎn)時(shí)的不便(比如從Controler類跟蹤到Service類時(shí),只能跳轉(zhuǎn)到接口類的相應(yīng)函數(shù),還要再按一次復(fù)雜的熱鍵才跳轉(zhuǎn)到實(shí)現(xiàn)類)
連Martin Flower都說,強(qiáng)制每個(gè)類都分離接口和實(shí)現(xiàn)是過猶不及。只在有多個(gè)獨(dú)立實(shí)現(xiàn),或者需要消除對(duì)實(shí)現(xiàn)類的依賴時(shí),才需要分離接口。
DAO被強(qiáng)制用接口的原因 Spring IOC本身是不會(huì)強(qiáng)制基于接口的,但DAO類一般要使用Spring的聲明式事務(wù)機(jī)制,而聲明式的事務(wù)機(jī)制是使用Spring AOP來實(shí)現(xiàn)的。Spring AOP的實(shí)現(xiàn)機(jī)制包括動(dòng)態(tài)代理和Cgilib2,其中Spring AOP默認(rèn)使用的Java動(dòng)態(tài)代理是必須基于接口,所以就要求基于接口了。
解決方法 那就讓Spring AOP改用CGLib2,生成目標(biāo)類的子類吧,我們只要指定使用聲明式事務(wù)的FactoryBean使用CGLib的方式來實(shí)現(xiàn)AOP,就可以不基于接口編程了。
指定的方式為
設(shè)置proxyTargetClass為true。如下:
<bean class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
id="baseService" abstract="true">
<property name="transactionManager" ref="transactionManager"/>
<property name="proxyTargetClass" value="true"/>


</bean>
又因?yàn)檫@些Service Bean都是單例,效率應(yīng)該不受影響。