2012-02-14 119 views
3

真正的問題是,爲什麼我能夠在這兩個方法來軟件寫此代碼:@autowired註釋如何工作?

@Controller 
public class PostController { 
@Autowired 
private PostService postService; 

@Autowired 
private CommentService commentService; 

.... 
} 

@Controller 
public class PostController { 

private PostService postService; 
private CommentService commentService; 

@Autowired 
public PostController(PostService postService, CommentService commentService){ 
    this.postService = postService; 
    this.commentService = commentService; 
} 

.... 
} 

是那些片段相同?推薦的是什麼?

回答

2

第一種解決方案直接注入反射值(基本上JVM將採取您的對象並手動設置值)。

第二個解決方案使用構造函數,這意味着該參數是必需的。另外,您有時間將自己的屬性分配給自己的屬性之前使用該值。 (注意構造函數也會被反射調用)。

另一種方法是使用setter,這次調用一個方法來設置值,以便在實際設置它之前使用它,但它不是強制性的(因爲它不是構造函數的一部分)。

關於推薦的一個,我不確定實際上有一個「正式推薦」,但我傾向於只使用構造函數注入的強制性領域和設置注入非強制性領域。但據我所知,它主要取決於你的團隊或你的品味。

1

你可以用兩種不同的方式編寫它們,因爲Spring決定支持從應用程序上下文中注入bean的兩種方式(甚至有三分之一!)。

他們會做同樣的事情大部分時間。但每個人在工作方式上都有細微的差異。請看documentation進一步澄清,因爲細節可以在那裏更好地解釋。

0

我希望在PostController中的構造函數返回後,注入第一個示例中的依賴項。在第二個例子中,我希望依賴項在構造函數執行時被注入。即第二個例子可以保證當構造函數執行時依賴關係存在,第一個例子不會。

0

從測試的角度來看,它們是不一樣的。 除非您有PostService和CommentService的setter方法,否則無法輕鬆設置它們的值。

通常爲@Autowired類似,其設定爲包範圍 而不是

@Autowired 
    private PostService postService; 

我們做

@Autowired 
    PostService postService; 

通知沒有 「私人」。

這樣做的原因是...... 只有具有相同包的類才能讀取/寫入該變量,以及何時執行測試類,通常是在與被測試單元相同的包下。