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注入的對象,支持開啟多線程異步訪問
使用場景,見文末推薦。
寫在最后
哪位大佬如若發現文章存在紕漏之處或需要補充更多內容,歡迎留言!!!
相關推薦: