在某些特殊的情況下,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/
關於作者:專注於基礎平台的項目開發。如有問題或建議,請多多賜教!
版權聲明:本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。
特此聲明:所有評論和私信都會在第一時間回復。也歡迎園子的大大們指正錯誤,共同進步。或者直接私信我
聲援博主:如果您覺得文章對您有幫助,可以點擊文章右下角【推薦】一下。您的鼓勵是作者堅持原創和持續寫作的最大動力!