在上一篇文章里說到,我們對UserManagerImpl類所有的方法進行了spring事物控制,而UserManagerImpl實現了UserManager接口,也許有人會說我的業務邏輯又不經常改變,為何還要多寫這么一個接口,這不是很麻煩,接口的目的就是為了以后擴充業務邏輯而準備的,單改變業務邏輯的時候我重新實現一下這個接口,而不必要去動原有的實現類,而前期我業務邏輯很簡單,不會變化,為了達到敏捷編程,前期設計我想盡量保持簡單,這樣不好嗎?確實,前期盡量簡單后期再進行重構,思想是不錯,但由于spring的事物管理機制要么是基于AOP,或者CGLIB,要么是aspectJ,但這些技術都是基于代理技術實現,也就是說他們會拿其中某個類做為代理,然后返回一個代理對象,而當你的具有容器托管的業務邏輯類在沒有接口的情況下,spring會把具體的實現類做為代理來實現事物管理,在這種情況下,當你在客戶端代碼里用:
UserManager userManager = (UserManager)ServiceLocator.getService("userManager");的時候會報java.lang.ClassCastException錯誤,因為這樣得到對象不是UserManager的實現,而是spring返回一個形如:$Proxy這樣的代理對象,所以你就不能對它進行操作,怎么辦,無奈,你別無選擇,你只能為UserManagerImpl類建立一個接口,然后實現這個接口,那么spring就會用UserManager這個接口來做為代理,而不是UserManagerImpl來做為代理了,所以這就是為什么有事物控制時一定要有接口的原因!
?
其時在hibernate里,如果要用spring的基于aspectJ的AOP技術來進行事物控制的話,你的pojo對象最好不要有基類,也就是說最好不要有以下的形式出現POJO類:
public class User extends Entity {
}
如果是這樣的話,加載spring上下文的時候會出現Entity類找不到的情況,具體是什么原因,還在分析中,所以當你在基類的POJO對象時,最好不要用基于aspectJ的AOP技術來實現事物管理!
原貼地址:http://arden.javaeye.com/blog/30296
原貼地址:http://arden.javaeye.com/blog/30296