1. 程式人生 > >Spring 通過Autowired 和 Context.getBean()方式拿到的不是同一個Bean

Spring 通過Autowired 和 Context.getBean()方式拿到的不是同一個Bean

最近做專案需要在Listener中獲取一個Bean,首先會去getBean方式獲取,set一些值,然後Autowired注入的時候莫名丟失,感覺苦惱。

最終做過嘗試,使用下面方法解決這個問題:

public class BeanFactory implements BeanFactoryAware{

    private static org.springframework.beans.factory.BeanFactory beanFactory;
    @Override
    public void setBeanFactory(org.springframework.beans.factory.BeanFactory beanFactory) throws BeansException {
        this.beanFactory=beanFactory;
    }

    public static Object getBean(String beanId){
       return beanFactory.getBean(beanId);
    }

}

定義一個BeanFactory工具類,從該工具類中去獲取需要的Bean,至於原因後續再深究,解決問題為當前最重要的事情。

還有從別的部落格上面看到下面兩種解決方法,後續待驗證


package com.tang.back.web.listener;

import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.tang.back.dto.sys.DictionaryDetail;
import com.tang.back.impl.service.DictionaryServiceImpl;

/**
 * 獲取系統字典資料,快取在Application中以提高頁面初始化效能
 *
 * @author tang
 * @see [相關類/方法](可選)
 * @since [產品/模組版本] (可選)
 */
public class DataCacheListener implements ServletContextListener{
    
    private final static String DICTIONARY_CACHE = "dictionary";
    
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        final WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext()); // 關鍵程式碼
        final DictionaryServiceImpl dictionaryService = (DictionaryServiceImpl)springContext.getBean("dictionaryService"); // 關鍵程式碼
        
        ServletContext application = sce.getServletContext();
        Map<String, List<DictionaryDetail>> dict = dictionaryService.getAllDictionary();
        application.setAttribute(DICTIONARY_CACHE, dict);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        ServletContext application = sce.getServletContext();
        application.removeAttribute(DICTIONARY_CACHE);
    }

    
}

@Autowired private Properties props;

@Override
public void contextInitialized(ServletContextEvent sce) {
    WebApplicationContextUtils
        .getRequiredWebApplicationContext(sce.getServletContext())
        .getAutowireCapableBeanFactory()
        .autowireBean(this);

    //Do something with props
    ...
}    
上述兩種待後續驗證研究原因。