[英]Spring Java config, @Autowire vs. Constructor Injection, @Transactional and CGLIB
我們一直在使用@Autowired
和基於Java的Spring配置取得了一些成功,但現在我們失去了控制權。 每個人都開始在任何地方添加自動連接的依賴項,創建周期和奇怪的錯誤。
所以我們正在考慮使用構造函數注入和Spring配置的自動裝配。
舊:
class Bean {
@Autowired Foo foo;
}
@Configuration
@Import( FooCfg.class )
class BeanCfg {
@Bean public Bean bean() { return new Bean(); }
}
新:
class Bean {
public Bean(Foo foo) {...}
}
@Configuration
class BeanCfg {
@Autowired FooCfg fooCfg;
@Bean public Bean bean() { return new Bean(fooCfg.foo()); }
}
這非常有效(並且它驅使人們分割bean而不是創建具有10個以上構造函數參數的怪物)。
但是當Bean
有一個使用@Transactional
注釋的方法時失敗,因為CGLIB然后嘗試創建一個失敗的代理,因為它找不到無參數的構造函數。
這是什么解決方案?
您有幾種可能的解決方案
protected
無參數構造函數 在為類引入接口時,可以刪除CgLib的用法。 然后Spring將能夠使用JDK Dynamic Proxies來解決接口問題。 它圍繞一個已經存在的bean實例創建一個代理,該代理實現了它所包裝的類的所有接口。 這樣,你的類是否有一個無參數構造函數並不重要。
在Spring 4.0中,添加了支持以允許使用缺少的無參數構造函數來代理類(參見SPR-10594 )。 為了實現Spring版本的升級並將Objenesis添加到類路徑中,Spring 4附帶了自己的重新打包的cglib版本,因此不再需要它了。
需要注意的一點是,如果你在構造函數中進行空檢查或初始化邏輯,你應該有一個沒有邏輯的構造函數,在cglib創建實例的情況下它可能會失敗。 我懷疑它將null傳遞給所有構造函數參數(或者一些默認的基元)。
protected
無參數構造函數 Cglib需要能夠創建一個用於包裝實際類的實例。 在類中有一個protected
構造函數就足夠了,這樣cglib就可以調用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.