SpringBoot進階教程(六十九)ApplicationContextAware
在某些特殊的情況下,Bean需要實現某個功能,但該功能必須藉助於Spring容器才能實現,此時就必須讓該Bean先獲取Spring容器,然後藉助於Spring容器實現該功能。為了讓Bean獲取它所在的Spring容器,可以讓該Bean實現ApplicationContextAware介面。ApplicationContextAware 通過它Spring容器會自動把上下文環境物件呼叫ApplicationContextAware介面中的setApplicationContext方法。在ApplicationContextAware的實現類中,就可以通過這個上下文環境物件得到Spring容器中的Bean。看到—Aware就知道是幹什麼的了,就是屬性注入的,但是這個ApplicationContextAware的不同地方在於,實現了這個介面的bean,當spring容器初始化的時候,會自動的將ApplicationContext注入進來。
1. 新增實現ApplicationContextAware的工具類
package learn.utils; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; /** * @author toutou * @date by 2020/12 * @des */ @Component public class SpringContextUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext context) throws BeansException { applicationContext = context; } public static ApplicationContext getApplicationContext() { return applicationContext; } //獲取Bean public static <T> T getBean(Class<T> requiredType){ return getApplicationContext().getBean(requiredType); } public static <T> T getBean(String name){ return (T) getApplicationContext().getBean(name); } }
2. 介面中直接呼叫
@GetMapping("home") public Result getUser(){ UserAccountService userAccountService = SpringContextUtil.getBean(UserAccountService.class); return Result.setSuccessResult(userAccountService.getUserAccountById(1)); }
3. service中內部呼叫
由於專案中配置了多個數據源,若所有mybatis mapper訪問都集中在單個service方法中,@AutoDBDecision宣告的資料來源會串。所以需要顆粒化。這樣就會在單個service中需要請求內部的方法,這時候也可以用上ApplicationContextAware工具類。
3.1 service中宣告內部專用呼叫方法inside()
/** * @author toutou * @date by 2020/12 * des https://www.cnblogs.com/toutou/ */ public interface UserAccountService { default UserAccountService inside() { return SpringContextUtil.getBean(UserAccountService.class); } UserAccountVO getUserAccountById(Integer id); UserAccountVO getUserAccountById2(Integer id); }
3.2 impl中呼叫方法
/** * @author toutou * @date by 2020/12 * des https://www.cnblogs.com/toutou/ */ @Service public class UserAccountServiceImpl implements UserAccountService{ @Autowired UserAccountMapper userMapper; public UserAccountVO getUserAccountById(Integer id){ UserAccountVO accountVO = null; UserAccount account = userMapper.selectByPrimaryKey(id); if (account != null) { accountVO = new UserAccountVO(); accountVO.setId(account.getId()); accountVO.setAccount(account.getAccount()); accountVO.setAge(account.getAge()); accountVO.setEmail(account.getEmail()); accountVO.setUsername(account.getUsername()); accountVO.setPhone(account.getPhone()); } return accountVO; } public UserAccountVO getUserAccountById2(Integer id){ return inside().getUserAccountById(id); } }
其他參考/學習資料:
- ApplicationContextAware (Spring Framework 5.3.2 API)
- How does ApplicationContextAware work in Spring?
- How to Get ApplicationContext in Spring Boot
v原始碼地址
https://github.com/toutouge/javademosecond/tree/master/hellolearn
作 者:請叫我頭頭哥
出 處:http://www.cnblogs.com/toutou/
關於作者:專注於基礎平臺的專案開發。如有問題或建議,請多多賜教!
版權宣告:本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。
特此宣告:所有評論和私信都會在第一時間回覆。也歡迎園子的大大們指正錯誤,共同進步。或者直接私信我
聲援博主:如果您覺得文章對您有幫助,可以點選文章右下角【推薦】一下。您的鼓勵是作者堅持原創和持續寫作的最大動力!