2017-06-28 2 views
0

Ich möchte einen geplanten Task im Spring Boot erstellen. Ich habe bereits eine Definition, die wie folgt aussieht:Geplanter Task im Spring Boot unter Verwendung des vorhandenen Controllers

@Component 
public class ScheduledTasks { 

    private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class); 
    private static long count = 0; 

    @Autowired 
    private TaskRepository taskRepository; 

    @Scheduled(fixedRate = 15000) 
    public void createTasks() { 

     count++; 

     Task t = new Task(); 
     t.setTitle("Scheduled Task " + count); 
     //TaskController tc = new TaskController(); 
     //tc.create(t); 
     taskRepository.saveAndFlush(t); 

     log.info("A new scheduled task has been created!"); 
    } 
} 

Das alles funktioniert gut, aber ich bin die Schnittstelle für meinen Repository direkt verwenden. Anstatt das Repository direkt zu verwenden, möchte ich die vorhandene Controller-Klasse verwenden, die ich habe. Ich habe eine Controller-Klasse, die wie folgt aussieht:

@RestController 
@RequestMapping("api/v1/") 
public class TaskController { 

    @Autowired 
    private TaskRepository taskRepository; 

    @RequestMapping(value = "tasks", method = RequestMethod.POST) 
    public Task create(@RequestBody Task task) { 
     return taskRepository.saveAndFlush(task); 
    } 
} 

Also, wie kann ich diese Methode in der Klasse ScheduledTasks Aufgabenerstellung erstellen eigentlich nennen? Wenn ich versuche, etwas wie new TaskController() zu machen, wie ich es auskommentiert habe, bekomme ich einen Null-Referenzfehler. Irgendeine Idee, wie man das umgeht?

Antwort

1

Wenn Sie new TaskController() tun, wird die von Ihnen erstellte Instanz nicht von Spring verwaltet, daher wird der IoC (Autowiring der Abhängigkeiten) nicht passieren.

Ich glaube, dass Sie einfach die Spring verwaltete Instanz des Controllers verwenden möchten, in diesem Fall, einfach in der Komponente "ScheduledTask". (wie unten (ungetestet))

@Component 
public class ScheduledTasks { 

    private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class); 
    private static long count = 0; 

    @Autowired 
    private TaskRepository taskRepository; 

    @Autowired 
    private TaskController tc; 

    @Scheduled(fixedRate = 15000) 
    public void createTasks() { 

     count++; 

     Task t = new Task(); 
     t.setTitle("Scheduled Task " + count); 
     tc.create(t); 
     taskRepository.saveAndFlush(t); 

     log.info("A new scheduled task has been created!"); 
    } 
} 
+3

Während das technisch funktioniert, scheint es sehr falsch, diese Art von Funktionalität in Ihrer 'Controller' Klasse zu setzen. Das einzige Problem eines Controllers muss mit der Benutzeroberfläche sein. –

+4

Besser noch die allgemeine Funktionalität in eine Serviceklasse extrahieren und den Service sowohl im Controller als auch im Task verwenden! ✅ – Strelok

+0

Ich stimme zu, dass dies kein gutes Design ist, sollte es eine Trennung von Bedenken geben, und Sie würden wahrscheinlich diese Anmeldung in einer Service-Klasse abstrahieren (unter Verwendung der Service-Stereotype) und beide, die ScheduledTask und den Controller, verwenden der Service (autowired). – Oliver

Verwandte Themen