1. 程式人生 > >SpringBoot進階教程(六十九)ApplicationContextAware

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