SpringBoot進階教程(六十九)ApplicationContextAware

在某些特殊的情況下,Bean需要實現某個功能,但該功能必須藉助於Spring容器才能實現,此時就必須讓該Bean先獲取Spring容器,然後藉助於Spring容器實現該功能。爲了讓Bean獲取它所在的Spring容器,可以讓該Bean實現ApplicationContextAware接口。ApplicationContextAware 通過它Spring容器會自動把上下文環境對象調用ApplicationContextAware接口中的setApplicationContext方法。在ApplicationContextAware的實現類中,就可以通過這個上下文環境對象得到Spring容器中的Bean。看到—Aware就知道是幹什麼的了,就是屬性注入的,但是這個ApplicationContextAware的不同地方在於,實現了這個接口的bean,當spring容器初始化的時候,會自動的將ApplicationContext注入進來。

SpringBoot進階教程(六十九)ApplicationContextAware

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);
    }
}

其他參考/學習資料:

 

v源碼地址

https://github.com/toutouge/javademosecond/tree/master/hellolearn


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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章