1.16 Spring - Prototype in Singleton

問題: 若今天有個@Autowired bean (此稱bean A)存在於某個Singleton bean (此稱bean B)中, 且bean A必須為prototype bean, 請問該如何實現此種配置呢?

思路: 這裡可以考慮以下情境, 假設有個singleton bean (bean B), 此bean的角色是個controller, 然後在bean B中注入一個bean A (@Autowired), 而我們希望每次有request進到這個controller的時候, 這個bean A都會是一個新的bean (即prototype bean).

以下先定義Request:

/**
 * @author Carl Lu
 */
public class Request {

    Long id;
    String content;

    public static Request getInstance(Long id, String content) {
        Request request = new Request();
        request.setId(id);
        request.setContent(content);
        return request;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

再來是要被設定成prototype的bean A, 此處為validator:

然後是身為controller的singleton bean (bean B)

-> 就只是一個要處理request的class而已, 不過其中會注入bean A (prototype scope)

寫個test case來驗證看看:

結果:-> 看起來光是把Validator設定成prototype scope是沒有用的, 因為都是同一個instance. 原因我想應該是因為在create RequestHandler的時候, container已經把RequestHandler默認為一個singleton bean了, 所以它也只會把validator bean注入一次並且重用validator bean.

所以現在來修改一下, 以下是改良過後的validator:

-> 我後來查了一些資料, 我想這個解法是我覺得比較好看的, 首先要include cglib, 這邊的原理是利用AOP scoped proxies在每次RequestHandler被呼叫的時候都注入一個新的validator bean

重新測試:-> 這樣看起來是有達到效果了, 每個validator看來都是一個新的instance.

Last updated

Was this helpful?