1. 程式人生 > >自己new的物件怎麼注入spring管理的物件

自己new的物件怎麼注入spring管理的物件

本文主要參考了以下兩篇部落格,然後將兩者整合起來

正文:

    我這裡主要是想在專案中運用裝飾者模式,但是因為自己new出來的裝飾者service (不受spring管理)並沒有注入其他service時,但是我又確實需要去注入,這個時候就找到這兩個部落格,結合起來。

    使用方法:裝飾者service需要繼承這個類,然後裝飾者service正常new的時候,裝飾者service中註解了@Autowired的屬性就會在spring容器中找到並注入。

    理解:initNewService因為是被spring容器管理的,且實現了ApplicationContextAware(或者ServletContextAware

),所以在spring容器初始化的時候回注入ApplicationContextAware,我們把它儲存在類中,並設定為static,因此每個繼承此類的物件都能拿到ApplicationContextAware。然後繼承類初始化的時候,我們通過屬性的型別到容器中找到對應的物件,並通過反射注入進來。

    程式碼如下:

@Service
public class InitNewService implements ApplicationContextAware {

    private static Logger logger = LoggerFactory.getLogger(InitNewService.class);

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * 將繼承此類的service中的欄位(註解了@Autowired 或者@Resource)等注入進來
     */
    public InitNewService(){

        if (this.applicationContext == null){
            return;
        }

        if (this.getClass().isAnnotationPresent(org.springframework.stereotype.Service.class)
                || this.getClass().isAnnotationPresent(org.springframework.stereotype.Controller.class)
                || this.getClass().isAnnotationPresent(org.springframework.stereotype.Component.class) ){
            return;
        }

        Class clazz = this.getClass();
        do {
            Field[] fields = clazz.getDeclaredFields();
            for (Field f : fields) {
                if (f.isAnnotationPresent(org.springframework.beans.factory.annotation.Autowired.class)
                        || f.isAnnotationPresent(javax.annotation.Resource.class)){

                    try {
                        String simpleName = f.getType().getSimpleName();
                        String beanName = StrUtils.toLowerCaseFirstOne(simpleName);

                        Object bean = applicationContext.getBean(beanName);
                        if (bean == null){
                            return;
                        }

                        boolean accessible = f.isAccessible();
                        f.setAccessible(true);
                        f.set(this,bean);
                        f.setAccessible(accessible);
                    }catch (Exception e){
                        logger.error(clazz.getName() + "當new物件注入類" + f.getName() + "的時候,發生了錯誤",e);
                        e.printStackTrace();
                    }

                }
            }
            clazz = clazz.getSuperclass();
        } while (clazz != Object.class);
    }


}