SpringBoot如何使用ApplicationContext獲取bean對象
使用ApplicationContext獲取bean對象
編寫一個ApplicationContextFactory工廠類
public class ApplicationContextFactory{ private static ApplicationContext applicationContext = null; public static void setApplicationContext(ApplicationContext applicationContext) throws BeansException { applicationContext = applicationContext; } public static ApplicationContext getApplicationContext(){ return applicationContext; } }
在SpringBoot的啟動類中設置ApplicationContext
public class Application { public static void main(String[] args) { ConfigurableApplicationContext app = SpringApplication.run(Application.class, args); ApplicationContextFactory.setApplicationContext(app); } }
通過ApplicationContextFactory獲取SpringApplication從而獲取bean對象
ApplicationContext applicationContext=ApplicationContextFactory.getApplicationContext(); Clazz clazz = applicationContext.getBean(Clazz.class);
SpringBoot Bean註入的深入研究
下面代碼可正常運行
DemoService
@Service public class DemoService { public void save(){ System.out.println("DemoService save"); } }
CommonClass
@Component public class CommonClass { @Resource private DemoService demoService; public void fun(){ System.out.println("fun"); demoService.save(); } }
Controller
@Resource private CommonClass commonClass; @ResponseBody @GetMapping("/fun") public void fun(){ commonClass.fun(); }
下面代碼不能正常運行
DemoService
@Service public class DemoService { public void save(){ System.out.println("DemoService save"); } }
CommonClass
public class CommonClass { @Resource private DemoService demoService; public void fun(){ System.out.println("fun"); demoService.save(); } }
Controller
@ResponseBody @GetMapping("/fun") public void fun(){ CommonClass commonClass = new CommonClass(); commonClass.fun(); }
比較
比較兩個代碼發現後者與前者的區別:因後者的CommonClass 沒有使用@Component標註,所以在Controller中不能才用註入方式生成CommonClass對象,而是才用new的方式生成瞭該對象。
這樣一來,CommonClass 對象是手工創建,所以在它內部註入DemoService 對象的代碼就錯誤瞭。
解決方案
新建工具類
@Component public class ApplicationContextUtil implements ApplicationContextAware { private static ApplicationContext act; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { act = applicationContext; } /** * 根據bean的名字獲取工廠中對應的bean對象 * @param beanName * @return */ public static Object getBean(String beanName){ return act.getBean(beanName); } }
註:實際測試發現上面代碼中的static不能省略
DemoService
@Service public class DemoService { public void save(){ System.out.println("DemoService save"); } }
CommonClass
public class CommonClass { @Resource private DemoService demoService; public void fun(){ DemoService demoService = (DemoService) ApplicationContextUtil.getBean("demoService"); System.out.println("fun"); demoService.save(); } }
此處不再采用註入的方式獲取DemoService對象,而是通過工具類的方式
Controller
@ResponseBody @GetMapping("/fun") public void fun(){ CommonClass commonClass = new CommonClass(); commonClass.fun(); }
再次運行程序,一切正常
應用
在SpringBoot整合Shiro的案例中,自定義Realm時,需要使用Service的對象。因為自定義的Realm類不能使用@Component之類的註解註釋,所以使用本案例介紹的方法是正確的解決方案。盡管在1.6.0的shiro-all中下面代碼可以正確運行:
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- SpringBoot項目如何將Bean註入到普通類中
- springboot實現在工具類(util)中調用註入service層方法
- SpringBoot中的main方法註入service
- 關於spring中單例Bean引用原型Bean產生的問題及解決
- Springboot 如何獲取上下文對象