Spring 實現線程接口 Runnable 註解注入失敗 @Autowired @Resource annotation is not supported on static fields

原因就是spring和多線程安全的問題,不讓注入 
解決方案有以下幾種

一.變量前綴加static,生成set方法並加上@Resource或者@Autowired

變量前綴加static,生成set方法並加上@Resource或者@Autowired,記住把set方法 static 去掉,否則會拋出 @Resource annotation is not supported on static fields

private static VerificDao verificDao;

@Resource
public void setVerificDao(VerificDao verificDao) {
    CheckVoiceVerify.verificDao = verificDao;
}

 

二.根據spring上下文環境獲取bean


import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringContextUtils implements ApplicationContextAware {

    private static ApplicationContext applicationContext = null;

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

    }

    /** 獲取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);
    }


    /** 是否包含Bean */
    public static boolean containsBean(String name) {
        return getApplicationContext().containsBean(name);
    }

    /** 判斷該Bean是否是單例 */
    public static boolean isSingleton(String name) {
        return getApplicationContext().isSingleton(name);
    }

    /** 根據類型查找Bean */
    public static Class<? extends Object> getType(String name) {
        return getApplicationContext().getType(name);
    }

}

 

//        AuthUserMapper authUserMapper = (AuthUserMapper) SpringContextUtils.getBean("authUserMapper");
//        PrimaryAuthUserMapper primaryAuthUserMapper = (PrimaryAuthUserMapper) SpringContextUtils.getBean("primaryAuthUserMapper");

 

三. 在啓動這個線程的時候,在這個線程的構造函數中把需要注入的對象傳過去

new Thread(new CheckVoiceVerify(verifyService)).start();

 

 

例子:


import com.cqsym.mulmbds.entity.seconedaryentity.AuthUser;
import com.cqsym.mulmbds.mapper.primarymapper.PrimaryAuthUserMapper;
import com.cqsym.mulmbds.mapper.secondarymapper.AuthUserMapper;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class CopyTableToTestTableTask extends BaseTask {

    private static AuthUserMapper authUserMapper;

    private static PrimaryAuthUserMapper primaryAuthUserMapper;

    @Autowired
    public void setAuthUserMapper(AuthUserMapper authUserMapper) {
        CopyTableToTestTableTask.authUserMapper = authUserMapper;
    }

    @Autowired
    public void setPrimaryAuthUserMapper(PrimaryAuthUserMapper primaryAuthUserMapper) {
        CopyTableToTestTableTask.primaryAuthUserMapper = primaryAuthUserMapper;
    }

    @Override
    void doTask() {
//        AuthUserMapper authUserMapper = (AuthUserMapper) SpringContextUtils.getBean("authUserMapper");
//        PrimaryAuthUserMapper primaryAuthUserMapper = (PrimaryAuthUserMapper) SpringContextUtils.getBean("primaryAuthUserMapper");

        primaryAuthUserMapper.getAllAuthUser2();
        logger.info("primaryAuthUserMapper.getAllAuthUser2 已經被執行");

        List<AuthUser> authUserList = authUserMapper.getAllAuthUser2();
        logger.info("authUserMapper.getAllAuthUser2 已經被執行");
        List<List<AuthUser>> authUserListPartitions = Lists.partition(authUserList,50);
        for(List<AuthUser> list : authUserListPartitions) {
            for(AuthUser authUser : list) {
                logger.info(authUser.toString());
            }
            logger.info("---------50行中間間隔----------------");
            Integer resultInt = primaryAuthUserMapper.submitAuthUser(list);
            logger.info("primaryAuthUserMapper.submitAuthUser 已經被執行: " + resultInt);

        }
        logger.info("數據同步已經執行完成!!!");


    }

}

 


import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;

import com.cqsym.mulmbds.task.CopyTableToTestTableTask;
import com.cqsym.mulmbds.task.FirstJobTask;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;


@Configuration
public class ScheduledConfig implements SchedulingConfigurer {

    @Bean
    public ScheduledExecutorService concurrentTaskScheduler(){
        ScheduledThreadPoolExecutor executorService = new ScheduledThreadPoolExecutor(20);
        executorService.setCorePoolSize(20);
        executorService.setMaximumPoolSize(40);
        ThreadFactory threadFactory = new CustomizableThreadFactory("TaskExecutor---");
        executorService.setThreadFactory(threadFactory);
        executorService.setRejectedExecutionHandler(new ScheduledThreadPoolExecutor.CallerRunsPolicy());
        return executorService;
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        //taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
        taskRegistrar.setScheduler(concurrentTaskScheduler());

        CronTrigger firstCronTrigger = new CronTrigger("0/30 * * * * ?");
        FirstJobTask firstJobTask = new FirstJobTask();
        taskRegistrar.addTriggerTask(firstJobTask, firstCronTrigger);

        CronTrigger copyTableToTestTableTaskCronTrigger = new CronTrigger("1 0/5 * * * ?");
        CopyTableToTestTableTask copyTableToTestTableTask= new CopyTableToTestTableTask();
        taskRegistrar.addTriggerTask(copyTableToTestTableTask, copyTableToTestTableTaskCronTrigger );


    }

}

 

 

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