在小冷工作中遇到這麼一個小問題,當你的業務層物件交給spring管理之後,在普通的類中呼叫這個類中的方法時候,會有個問題這個類在呼叫時候會一直返回一個null,而且還會丟擲一個空指標異常。
小冷在遇到這個問題時候使用了各種方法發現很多都不能用,其中小冷羅列下生效的方法,並且網上還推薦使用的
1.在普通類種也將自己注入交給spring管理
首先看上面的,第一張圖片,那個普通類似交給了spring管理的,並在這個類中注入了使用的業務層類,這個時候呼叫這個類中的方法時候,發現這個業務類返回是一個null,至於原因小冷下面解釋。
還有一種
2.小冷使用例項化這個業務類,一般例項化的類會加入堆記憶體的這樣試一下發現也不行
3.使用類載入的方式將載入器在專案啟動時就呼叫這個載入器,然後通過載入後的spring類載入器呼叫載入,這種是可以的
綜上所述只有第三種方法可以,這個裡附上載入spring容器的中的例項化類的工具類
package com.util; /* * @desc:提供非SPRING管理類呼叫管理類的功能 * 注意在服務啟動的時候進行import,apllication中引入 */ import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class SpringUtil implements ApplicationContextAware { private static ApplicationContext applicationContext = null; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if (SpringUtil.applicationContext == null) { SpringUtil.applicationContext = applicationContext; } System.out.println("---------------------------------------------------------------------"); System.out.println("========ApplicationContext配置成功,在普通類可以通過呼叫SpringUtils.getAppContext()獲取applicationContext物件,applicationContext=" + SpringUtil.applicationContext + "========"); System.out.println("---------------------------------------------------------------------"); } //獲取applicationContext public static ApplicationContext getApplicationContext() { return applicationContext; } //通過name獲取 Bean. public static Object getBean(String name) { return getApplicationContext().getBean(name); } //通過class獲取Bean. public static <T> T getBean(Class<T> clazz) { return getApplicationContext().getBean(clazz); } //通過name,以及Clazz返回指定的Bean public static <T> T getBean(String name, Class<T> clazz) { return getApplicationContext().getBean(name, clazz); } }
使用方式工具類中有註釋;就不一一贅述
這裡小冷按自己理解說一下為啥前兩種方式無法使用,如有不同理解和更為準確的解釋歡迎私信留言!!!!關注我公眾號“秦川以北”
先說一下第一種:小冷理解在看原始碼時候是由於在使用@Component註解和@Autowired時注入的例項未初始化,這時候spring容器中接收不到未初始化的例項,這個解決方案,在注入的同時初始化這個例項讓spring掃描到這個例項然後加入容器
@Component public class ComponentClass { @Autowired private JedisClient jedisClient; public static ComponentClass componentClass; @PostConstruct public void init(){ componentClass = this; componentClass.jedisClient = this.jedisClient; } }
第二種:第二種事由於例項化的業務類在自己類種引用了spring容器種的例項類,這個時候例項化的類在堆記憶體種,而spring容器在自己的堆存種中,他們不在同一個堆中可能這是例項化失效的關鍵。
以上都是小冷個人理解如有不同見解歡迎留言懟,有的原始碼小冷也是看的一知半解。