在小冷工作中遇到這么一個小問題,當你的業務層對象交給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容器在自己的堆存種中,他們不在同一個堆中可能這是實例化失效的關鍵。
以上都是小冷個人理解如有不同見解歡迎留言懟,有的源碼小冷也是看的一知半解。