1. 程式人生 > >Java 8 對Field injection的處理

Java 8 對Field injection的處理

在之前的文章裡Field injection is not recommended介紹了為什麼要儘量避免Field injection, 這篇文章主要介紹如何解決該問題.

使用Field injection的程式碼像下面

class controller{
@Auowired
private A a;

...
}

Java8 之前, 推薦使用的是constructor injection, 我們的處理變為

class controller{
private A a;

@Auowired
public controller(A a){
this.a=a;
}}

改成上方式的話, new controller的時候, 就必須使用引數. 這對於使用IDE的程式設計師來說, 可以很好的避免了bug(空指標). 然而, 自由性被限制, 當我們不確定某些屬性是否一定要實現時, construct method 要寫若干個, 程式碼量也增加了.

class controller{
private A a;
...
@Auowired
public controller(A a){
this.a=a;
}
public controller(A a,B b){
...
}
public controller(A a,B b,C c){
...
}}

上述程式碼, 如果對映到程式設計思想, 也就是COC(convention over configuration), 我們希望要修改的地方得到修改即可.

綜上 Java 8 之前的field injection 和 constructor injection的優點, 我們可以使用optional類.
實現程式碼如下:

class controller{
@Autowired
private Optional<A> a;
}

這裡有兩個問題, 1.原始碼中使用到A類的如何改? 2.Optional會自動匹配到A介面的實現類嗎?

1)原始碼中使用到A類的如何改?
原來的程式碼

methodA(){
if(a!=null) dosomething;
}
methodB(){
if(a!=null) return something;
}

對應則是

methodA(){
if(a.isPresent()) dosomething;
}
methodB(){
if(a.isPresent()
)
return something; } methodB(){ a.get(); }

當然, 也可以如下

methodA(){
a.map(a->dosomething);
}
methodB(){
a.ifPresent(a->dosomething);
}

方法若干… 函式式的方法, 基本都對應一個場景, 需要多看Javadoc

2)Optional會自動匹配到A介面的實現類嗎?

答: 會

摘自IBM

使用 @Autowired 註解進行裝配,只能是根據型別進行匹配。@Autowired 註解可以用於 Setter 方法、建構函式、欄位,甚至普通方法,前提是方法必須有至少一個引數。@Autowired 可以用於陣列和使用泛型的集合型別。然後 Spring 會將容器中所有型別符合的 Bean 注入進來。@Autowired 標註作用於 Map 型別時,如果 Map 的 key 為 String 型別,則 Spring 會將容器中所有型別符合 Map 的 value 對應的型別的 Bean 增加進來,用 Bean 的 id 或 name 作為 Map 的 key。

上述文章說道, map是可以匹配得到的, 所以這種機制同樣適用於optional.

測試程式碼如下:

  @Autowired
   Map<String, Object> a;

    @RequestMapping(value = "/iaaa")
    public void a() 
        System.out.println(a.size());
    }