不用注入方式使用Spring管理的對象中的方法,神奇


在小冷工作中遇到這么一個小問題,當你的業務層對象交給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容器在自己的堆存種中,他們不在同一個堆中可能這是實例化失效的關鍵。

以上都是小冷個人理解如有不同見解歡迎留言懟,有的源碼小冷也是看的一知半解。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM