2016-01-03 8 views
12

quello che presumo è una questione fondamentale abbastanza qui-Primavera io @Autowired: Il campo finale vuoto potrebbe non essere stato inizializzato

Ci sono diversi sapori di domande riguardanti questo errore, ma nessuno nei primi 5 risultati che hanno la sfumatura aggiunta di Spring.

Ho l'inizio di una webapp REST-ful scritta in primavera. Sto cercando di collegarlo a un database.

Ho un lavoro entità denominata e sto cercando di utilizzare l'iniezione di primavera di un fagiolo (terminologia corretta?) Per salvare l'istanza dell'entità lavoro

package com.parrit; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.util.Assert; 
import org.springframework.web.bind.annotation.RequestBody; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RestController; 

import com.parrit.models.Workspace; 
import com.parrit.models.WorkspaceRepository; 

@RestController 
@RequestMapping("/workspace") 
public class WorkspaceController { 

    @Autowired 
    private final WorkspaceRepository repository; 

    @RequestMapping(method = RequestMethod.POST) 
    void save(@RequestBody String workspaceHTML) { 
     Workspace ws = new Workspace(); 
     ws.setHTML(workspaceHTML); 
     repository.save(ws); 
    } 
} 

Il mio errore è sulla variabile repository private final WorkspaceRepository repository. Il compilatore si lamenta che potrebbe non essere inizializzato e il tentativo di eseguire l'app produce lo stesso risultato.

Come posso ottenere un'istanza di questo oggetto repository nel mio controller per poter salvare le operazioni su di esso?

risposta

20

Avere @Autowired e la finale su un campo sono contraddittorie.

Quest'ultimo dice: questa variabile ha uno e un solo valore ed è inizializzata in fase di costruzione.

Il primo dice: Spring costruirà l'oggetto, lasciando questo campo come null (il suo valore predefinito). Quindi Spring utilizzerà la reflection per inizializzare questo campo con un bean di tipo WorkspaceRepository.

Se si desidera che i campi finali autowired, utilizzare l'iniezione costruttore, proprio come si farebbe se avete fatto l'iniezione da soli:

@Autowired 
public WorkspaceController(WorkspaceRepository repository) { 
    this.repository = repository; 
} 
5

Esattamente, è necessario fornire un costruttore che assegna il campo finale

private final WorkspaceRepository repository; 

@Autowired 
public WorkspaceController(WorkspaceRepository repository){ 
    this.repository = repository; 
} 

E Primavera sarà in grado di capire come per inizializzare l'oggetto e iniettare il repository tramite il costruttore