2013-04-18 18 views
13

Runnable'ı uygulayan ve TaskExecutor autowired yaylarına gönderilen bir sınıfa nasıl sahip olabilirsiniz?Autowiring Görevleri Spring TaskExecutor'a gönderildi

public class MyTask implements Runnable { 

    @Autowired private MyRepository myRepository; 

    @Override 
    public void run() { 
     myRepository.doSomething(); 
    } 
} 

Ve bahar TaskExecutor bir görev gönderen bir servis:

@Service 
public class MyService { 

    @Autowired private TaskExecutor taskExecutor; 

    public void someMethod() { 

     MyTask myTask = new MyTask(); 
     taskExecutor.execute(myTask); 

    } 

} 

Ben MyTask çünkü alanları autowired edilmiyor biliyorum Örneğin

, ben Görev var Yeni MyTask() kullanarak örnekleniyor. Ancak, bu konuda nasıl alabilirim? Spring'in ApplicationContext'ine erişip, fasulyeyi bunun üzerinden yaratmalı mıyım? Bunu bir web uygulama ortamında nasıl yaparsınız?

Teşekkürler!

cevap

4

olarak MyService değiştirebilir. İlk olarak, @Configurable ek açıklaması. Bunun kullanılması AspectJ'e bağımlılık anlamına gelir, ancak Spring tarafından yönetilmeyen çekirdeklerin enjekte edilmesine izin verir (yani yeni operatörü kullanıyorsunuz). Bu, MyTask'ın @Configurable ile eklenmesi ve bağlantıda belirtildiği gibi Spring konfigürasyonunuza birkaç satır eklenmesi anlamına gelecektir.

@Configurable 
public class MyTask implements Runnable { ... } 

@Service 
public class MyService { 
    @Autowired private TaskExecutor taskExecutor; 

    public void someMethod() { 

    // AspectJ would jump in here and inject MyTask transparently 
    MyTask myTask = new MyTask(); 
    taskExecutor.execute(myTask); 

} 

}

İkinci yaklaşım prototip fasulye oluşturmak için Bahar ServiceLocatorFactoryBean özelliğini kullanmanızı gerektirir. olur

@Service 
public class MyService { 
    @Autowired private TaskExecutor taskExecutor; 
    @Autowired private MyRepository myRepository; 
    @Autowired private TaskFactory taskFactory; 


public void someMethod() { 
    MyTask myTask = taskFactory.getTask("myTask") 
    taskExecutor.execute(myTask); 
} 

}

MyTask: Bu en iyi JavaDoc açıklanmıştır, ancak bu gibi durumlarda, tıpkı diğer fasulye gibi, @Service açıklamalı sınıfa bir TaskFactory enjekte edilmesinin ardından bu yüzden böyle bir şey yapmak XML eşlemenizde bunu yapılandırabileceğiniz için zaten deponuza enjekte edilir. Bu yaklaşımların her ikisini de günlük olarak kullanıyorum, ancak daha kolay okunabilir ve kolay test edilebilir olmayan şeyler yapmamalarını sağlayarak geliştiricilerin d gündelik gözlemciye açık.

11

public class MyTask implements Runnable { 
    private MyRepository myRepository; 

    public MyTask(MyRepository myRepository) { 
     this.myRepository = myRepository; 
    } 

    @Override 
    public void run() { 
     myRepository.doSomething(); 
    } 
} 

@Service 
public class MyService { 
    @Autowired private TaskExecutor taskExecutor; 
    @Autowired private MyRepository myRepository; 


    public void someMethod() { 
     MyTask myTask = new MyTask(myRepository); 
     taskExecutor.execute(myTask); 
    } 
} 

deneyin veya bu kullanarak bahar yapmak için en az iki iyi yolu vardır MyTask kapsamını = "prototip" ilan edip

@Service 
public class MyService { 
    @Autowired private ApplicationContext ctx; 

    public void someMethod() { 
     MyTask myTask = ctx.getBean(MyTask.class); 
     taskExecutor.execute(myTask); 
    } 
} 
+0

Evet, bu işe yarar. Autowiring'in görevde çalışmasını umuyordum çünkü çok sayıda bağımlılığım var ve hepsinden daha fazlasını geçmemek istiyorum - bununla ilgili bir yol olmayabilir. –

+1

Başka bir yol var, bkz. Güncelleme –

+0

@EvgeniyDorofeev MyTask'ı prototip olarak nasıl tanımlarım? – Dejell