Java使用invoke反射調用方法導致@Value、@Autowired等註解失效

發生背景:開發過程中使用到invoke進行反射調用serviceImpl實現類的方法,在運行中發現採用反射方式調用會導致實現類中@value以及@Autowired註解失效,對應註解值都爲null。

原因:因爲在調用invoke反射方法時,Class是直接使用newInstance靜態方法來實例化對象。所導致對應@value、@Autowired等註解失效。

PS:Spring的註解是在Spring實例化的時候掃描注入,當Spring實例化完畢之後如果再去newInstance一個新的對象顯然是不受Spring管理了,所以相應的註解都是注入爲null。

Class baseService = serviceClassMap.get(taskRecord.getPlateform());
// 獲取指定Method方法
String methodStr = CommonMethodEnum.hasMethod(taskRecord.getType());
Method method = baseService.getMethod(methodStr,Long.class,File.class);
method.invoke(baseService.newInstance(), taskRecord.getId(), file);

解決方案:使用SpringContext上下文獲取對應Bean,從而避免註解失效。

method.invoke(SpringUtil.getBean(baseService), taskRecord.getId(), file);

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~SpringUtil工具類~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

採用實現接口ApplicationContextAware從而獲取ApplicationContext

說明:實現該接口的setApplicationContext(ApplicationContext context)方法,並保存ApplicationContext 對象。Spring初始化時,會通過該方法將ApplicationContext對象注入。

public class SpringContextUtil implements ApplicationContextAware {  
  
    // Spring應用上下文環境  
    private static ApplicationContext applicationContext;  
  
    /** 
     * 實現ApplicationContextAware接口的回調方法。設置上下文環境 
     *  
     * @param applicationContext 
     */  
    public void setApplicationContext(ApplicationContext applicationContext) {  
        SpringContextUtil.applicationContext = applicationContext;  
    }  
  
    /** 
     * @return ApplicationContext 
     */  
    public static ApplicationContext getApplicationContext() {  
        return applicationContext;  
    }  
  
    /** 
     * 通過name獲取對象 
     *  
     * @param name 
     * @return Object
     * @throws BeansException 
     */  
    public static Object getBean(String name) throws BeansException {  
        return applicationContext.getBean(name);  
    }
    
    /** 
     * 通過class獲取對象 
     *  
     * @param class
     * @return T
     * @throws BeansException 
     */  
    public static <T> T getBean(Class<T> clazz) throws BeansException {  
        return applicationContext.getBean(clazz);  
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章