1.情景展示
像枚舉類中注入spring管理的bean對象雖然不常見,但是,也有它對應的使用場景,如何實現?
2.原因分析
以springboot為例,可像普通類那樣通過注解@Autowire或@Resource注入對象。

如上圖所示,在枚舉類中也是可以使用@Resource或@Autowired注入對象,一開始我以為不可以,后來發現其實也是可以噠;
只不過,平常我們在類中注入對象是寫在類的最前面(作為類的私有屬性),而在枚舉中,需遵循:枚舉對象在最上面,私有屬性在下面;
這就會出現一個問題,因為枚舉類在最上面,而注入的對象在下面(代碼先后順序問題),所以,我們無法在添加枚舉類的時候,就為屬性interfaceType賦值;

這就很尷尬,不過好在有注解@PostConstruct,被該注解聲明的方法,會在注解@Resource或@Autowired執行后,再執行;
這樣一來,我們就可以在PostContruct()方法中拿到注入的bean對象,進而就可以為指定的枚舉類重新為其屬性interfaceType進行賦值;
這樣,就實現了:為不同的接口注入不同的業務實現類,也就是不同接口可以自動調用各自的業務處理類。
但是,在實際測試中發現,注入的bean對象還是為空。
3.解決方案
// @Setter不支持直接聲明在枚舉類上
@Getter
@AllArgsConstructor
public enum CzInterfaceEnum {
// 下面有枚舉類的構造方法
INTERFACE_CZ5101("cz5101");
@JsonValue
private String interfaceName;
// 接口類型
@Setter
private InterfaceCz interfaceType;
/**
* 為枚舉類注入spring管理的bean對象
* @description:
* @attention: 對象的注入必須創建一個單獨的類來完成,不然注入的對象都是null
* @author: Marydon
* @date: 2020年10月29日 0029 17:47
* @version: 1.0
* @email: marydon20170307@163.com
*/
@Component
public static class EnumTypeServiceInjector {
// 為該類注入對象
@Resource private InterfaceCz cz5101Impl;
/*
* 將注入的對象添加到對應的枚舉類中
* @attention:
* @date: 2020年11月13日 0013 19:02
* @param:
* @return: void
*/
// @Autowired, @Resource執行后會走該注解
@PostConstruct
private void postConstruct() {
INTERFACE_CZ5101.setInterfaceType(cz5101Impl);
}
}
/*
* 創建只有一個參數的構造方法
* @explain: 創建枚舉類(只給一個屬性賦值)
* 另一個屬性通過EnumTypeServiceInjector注入對象並賦值
* @attention:
* @date: 2020年11月13日19:13:01
* @param: interfaceName 接口名稱
* @return:
*/
CzInterfaceEnum(String interfaceName) {
this.interfaceName = interfaceName;
}
}
這樣,當我們使用枚舉的時候,就能獲得它所注入的對象。
說明:
通過@Autowire或@Resource注入的對象,支持開啟多線程異步訪問
使用場景,見文末推薦。
寫在最后
哪位大佬如若發現文章存在紕漏之處或需要補充更多內容,歡迎留言!!!
相關推薦:
