程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java對象序列化所引起的循環引用的思考

Java對象序列化所引起的循環引用的思考

編輯:關於JAVA

在Java中的模型關系設計中,循環的關系是很常見的,特別是ORM的出現,關系的循環更加有利於維護各自的狀態。但就是這種循環的關系,在Java對象序列化時,不可避免的會導致循環引用(Cycle Reference)的問題。

導致CycleReference的情況

還是舉個例子吧(代碼說話):一個很典型,很常見的雙向引用的對象關系。

@Entity

public class Company{

@Id

@Column(....)

private String id;

@OneToMany(....)

private Employee employee;

//setters/getters

......

}

@Entity

public class Employee{

@Id

@Column(....)

private String id;

@ManyToOne

private Company company;

//setters/getters

......

}

另外一種導致這個問題的情況是,多個對象間關系形成一條回路,跟電學有點像。(具體就不舉例了,在模型設計時,最好還是避免出現這種情況。)

導致這種問題的原因

用jaxb(如果沒有特殊解釋,本文采用的都是jaxb)序列化Company時,無疑會發生循環引用。

當序列化引擎解析Company時,它發現這個對象持有一個Employee的引用,轉而去騷擾Employee.解析Employee時,發現他又持有Company的引用,又轉回Company.如此問題產生。

引擎它並不知道在遇到循環引用問題時,該怎麼處理,它只是忠實得按照固定的算法去執行任務。所以我們得讓引擎聰明點,我們得讓引擎遇到這種問題有處理機制。

解決問題

既然需要引擎更聰明,那就沒辦法,就得燒香拜佛,希望制造商的產品擴展性足夠好,考慮了足夠多的情況。

幸運的是,jaxb提供了有這種擴展。(CycleRecoverable接口)

行軍打仗(例子先行):(將以上的例子改下)

@Entity

public class Company implements CycleRecoverable{

@Id

@Column(....)

private String id;

@OneToMany(....)

private Employee employee;

//當遇到循環引用時,用temp替代this,返給jaxb解析。

public Object onCycleDetected(Context arg0) {

Company temp = new Company ();

temp.setId(id);

return temp;

}

//setters/getters

......

}

@Entity

public class Employee implements CycleRecoverable{

@Id

@Column(....)

private String id;

@ManyToOne

private Company company;

public Object onCycleDetected(Context arg0) {

Employee temp = new Employee();

temp.setId(id);

return temp;

}

//setters/getters

......

}

注意到onCycleDetected方法就是一個回調方法,當遇到循環引用時,jaxb引擎會調用這個方法,用return對象來替換this.所以在這個過程中,就可以將引起循環引用問題的關系斷開,返回給jaxb.

當然Company和Employee對象沒必要全部實現CycleRecoverable接口,但是拿到現實的模型圖中去,誰也保證不了他們不跟別的對象有循環的關系存在。因此還是建議大家把模型都實現這個接口,也好一勞永逸。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved