@Autowired无法在可运行的

时间:2016-06-25 08:00:18

标签: java multithreading spring-mvc autowired

我有一个可运行的任务,我正在尝试Autowire字段,但是当我这样做时,任务不会运行。 当我在可运行的区域外自动移动它时它工作正常。为什么会这样?除了在内部自动装配之外,还有其他更清晰的方法可以在runnable中获取自动装配字段的新实例吗?

这是我的runnable方法`

Runnable task = new Runnable() {

                @Autowired
                ICruxPanelClientService CruxPanelClientService;

                public void run (){
            CruxPanelClientService.setCruxWebServiceBaseURL("http://10.41.181.23:8080");
            CronCruxModel m = new CronCruxModel();
            m = model1.get(model_var);
            System.out.println("EXECUTING");
            System.out.println(m.getService_status() + " ---------EXEexecution");
            System.out.println(m.getCat_name() + "Executing Name ");
        //  time = m.getService_time();
            UpdateCategoryRequest updateCategoryRequest = new UpdateCategoryRequest();
            CategoryModel categoryModel = new CategoryModel();
            categoryModel.setColor(m.getCat_color());
            categoryModel.setIcon(m.getCat_icon());
            categoryModel.setIconWhite(m.getCat_icon_white());
            categoryModel.setName(m.getCat_name());
            categoryModel.setId(m.getCat_id());
            categoryModel.setKey(m.getCat_catkey());
            categoryModel.setIndexOrder(m.getCat_indexOrder());
            updateCategoryRequest.setCategory(categoryModel);
            CruxPanelClientService.updateCategory(updateCategoryRequest);
            GetServiceDataIdByCategoryIdRequest request1 = new GetServiceDataIdByCategoryIdRequest();    
            request1.setId(m.getCat_id());
            GetServiceDataIdByCategoryIdResponse response1 = CruxPanelClientService.getServiceDataIdByCategoryId(request1);
            ArrayList<ServiceModel> service = new ArrayList<ServiceModel>();
            service = response1.getServiceModels();

            JSONArray json = new JSONArray();
            if(m.getService_order_succ_msg()==null)
            {
                json = new JSONArray();
            }
            else {

                 json = new JSONArray(m.getService_order_succ_msg());
            }
            String message = m.getService_order_succ_msg();

            for (int j=0;j<service.size();j++)
            {   
                UpdateServiceMasterRequest req = new UpdateServiceMasterRequest();
                ServiceModel s = new ServiceModel();
                s=service.get(j);
                ;
                JSONObject obj = new JSONObject();

                if(json.length()==0 ) 
                {
                    String ms = null;
                    s.setOrderSuccessMessage(ms);
                    req.setServiceModel(s);

                }

                else {

                    String message1 = json.get(j).toString();

                    if(message1.equals(null) || message1.equals("")) {
                        String ms = null;
                        s.setOrderSuccessMessage(ms);
                        req.setServiceModel(s);

                    }
                    else {
                        s.setOrderSuccessMessage(message1);

                        req.setServiceModel(s);

                    }
                }
                CruxPanelClientService.updateServiceMaster(req);

            }
            m.setService_status("executed");
            UpdateCronCruxRequest q = new UpdateCronCruxRequest();
            q.setCronCruxModel(m);
            CruxPanelClientService.updateCronCrux(q);

                }
            };`

4 个答案:

答案 0 :(得分:4)

@Autowire不能用于匿名类(因为你调用new,而不是Spring),你可以在外部类中自动装配一个字段,然后在Runnable内使用该字段

或者让Runnable成为一个完整的类(不是匿名的)并使其成为一个bean(和autowire,例如使用id

答案 1 :(得分:2)

问题是spring无法控制可运行对象的创建。有两种可能的解决方案:

  1. 将可运行的创建放入某些服务,存储库,控制器,组件或spring处理过的内容中:

示例:

@Service
public class SomeService {

    @Autowired
    private ICruxPanelClientService cruxPanelClientService;

    public Runnable newRunnable() {

        return new Runnable() {

            public void run() {
                cruxPanelClientService <- will be visible here and injected
            }
        }
    }

}
  1. 使用原型范围创建可运行为Bean

示例:

@Configuration
public class Runnableconfiguration {

    @Bean
    @Scope("prototype")
    public Runnable newRunnbale(final ICruxPanelClientService cruxPanelClientService) {
        return new Runnable() {
            public void run() {
                cruxPanelClientService <- will be visible here
            }
        }
    }
}

答案 2 :(得分:1)

Spring不会@autowire将任何东西new放入非托管实例(与Spring创建和管理的实例相反,您使用@autowire创建的实例)。

这将为您提供以下选择:

  • Runnable外部的依赖项,并将其传递给Runnable(或使Runnable可以访问)。
  • 创建一个子类@autowire的新类,并在您需要的地方applicationContext.getBean(..)
  • 不需要注入依赖项,而是在需要时查找它(procedure TForm1.GetsSytemDateFormat; var myDate : string; begin myDate:=GetLocaleStr(GetThreadLocale(), LOCALE_SSHORTDATE, ''); edtSysDefault.Text := myDate; end; )。

使用线程时,请小心作用域和延迟初始化,因为某些Spring作用域(例如“ request”或“ session”作用域)是线程本地绑定的(例如,使用延迟请求时)范围内的新线程中的依赖项,该线程在执行时不再与当前请求关联。

答案 3 :(得分:0)

除了上述所有内容外,也许最好从可运行对象外部插入服务,而不要在可运行内部使用@Autowired。因此,在您的情况下:

Runnable task = new Runnable() {

                @Autowired
                ICruxPanelClientService CruxPanelClientService;

将成为:

@Autowired
private ICruxPanelClientService CruxPanelClientService;

Runnable task = new Runnable() {
...
}