2017-05-10 77 views
0

我有以下问题:我有一个扩展了UI的Mainview类。在这个类中依赖注入的作品。但是这个班有一个有意见的导航员。该视图保存也包含视图的Tabsheet。现在我需要在视图中注入一个Spring @Service类。但是DI链已经坏掉了。我已经知道依赖注入链不应该被打断(我在这里通过另一个问题发现了这一点)。但我找不到保持这条链条活着的方法。有人有一个很好的tipp如何实现意见beeing也注入,尽管这样我可以在任何地方使用导航?我认为我做得太复杂甚至错了。这是我的MAINVIEW(扩展UI)类:用Vaadin和Spring Boot实现依赖注入的好实践

@Theme("valo") 
@SpringUI 
public class MainView extends UI { 

private static final long serialVersionUID = 1L; 
private static final Logger LOGGER = LoggerFactory.getLogger(MainView.class); 
public static Navigator navigator; 
private List<String> availableRealms = new ArrayList<>(); 
private ComboBox<String> select =new ComboBox<>(); 

@Autowired 
private SpringViewProvider viewProvider; 


@Override 
protected void init(VaadinRequest request) { 
    LOGGER.info("Initializing MainView container..."); 
    createMainView(); 

} 

public void createMainView(){ 
    HorizontalLayout comboBoxLayout = new HorizontalLayout(); 

    comboBoxLayout.addComponent(select); 
    availableRealms.add("Master-Realm"); 
    select.setTextInputAllowed(false); 
    select.setItems(availableRealms); 
    select.setSelectedItem(availableRealms.get(0)); 
    LOGGER.info("Building mainView area..."); 
    final VerticalLayout root = new VerticalLayout(); 
    root.setSizeFull(); 
    root.setMargin(true); 
    root.setSpacing(true); 
    setContent(root); 
    final CssLayout navigationBar = new CssLayout(); 
    //  navigationBar.addComponent(comboBoxLayout); 
    navigationBar.addStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP); 
    navigationBar.addComponent(createNavigationButton("Dashboard",DashBoardView.VIEW_NAME)); 
    navigationBar.addComponent(createNavigationButton("Realm Settings",RealmSettingsView.VIEW_NAME)); 
    navigationBar.addComponent(createNavigationButton("Client Management",ClientManagementView.VIEW_NAME)); 
    navigationBar.addComponent(createNavigationButton("User Management",UserManagementView.VIEW_NAME)); 
    navigationBar.addComponent(createNavigationButton("Group Management",GroupManagementView.VIEW_NAME)); 
    comboBoxLayout.addComponent(navigationBar); 

    root.addComponent(comboBoxLayout); 
    //  root.addComponent(navigationBar); 

    final Panel viewContainer = new Panel(); 
    viewContainer.setSizeFull(); 
    root.addComponent(viewContainer); 
    root.setExpandRatio(viewContainer, 1.0f); 
    LOGGER.info("Initializing navigator..."); 
    navigator = new Navigator(this, viewContainer); 
    navigator.addProvider(viewProvider); 
    navigator.addView("", DashBoardView.class); 

} 

/** 
* Creates a new button with listener that uses the navigator. 
* @param caption 
* @param viewName 
* @return <b>Button</b> 
*/ 
private Button createNavigationButton(String caption, final String viewName) { 
    Button button = new Button(caption); 
    button.addStyleName(ValoTheme.BUTTON_SMALL); 
    // If you didn't choose Java 8 when creating the project, convert this to an anonymous listener class 
    button.addClickListener(event -> getUI().getNavigator().navigateTo(viewName)); 
    return button; 
} 

}

这是持有一个标签页的ClientManagementView:

@SpringView(name = ClientManagementView.VIEW_NAME) 
@ViewScope 
public class ClientManagementView extends VerticalLayout implements View { 

private final Logger LOGGER = LoggerFactory.getLogger(ClientManagementView.class); 

private static final long serialVersionUID = 1L; 

public static final String VIEW_NAME = "clientmanagementview"; 

@Autowired 
ClientOverview clientOverview; 

@Autowired 
ClientCreationView clientCreationView; 

@Autowired 
private TabSheet tabsheet; 

@PostConstruct 
void init() { 
    LOGGER.info("Initializing ClientView..."); 
    setSizeFull(); 
    setSpacing(true); 
    setMargin(true); 
    //  TabSheet tabsheet = new TabSheet(); 
    tabsheet.addStyleName(ValoTheme.TABSHEET_FRAMED); 
    this.addComponent(tabsheet); 
    tabsheet.addTab(clientOverview); 
    tabsheet.addTab(clientCreationView); 
} 

@Override 
public void enter(ViewChangeEvent event) { 
    // do nothing. 

} 

} 

而现在的客户端创建视图:

@SpringView(name = ClientCreationView.VIEW_NAME) 
@ViewScope 
public class ClientCreationView extends VerticalLayout implements View { 


private static final long serialVersionUID = 1L; 
public static final String VIEW_NAME = "client_creationview"; 
private final Logger LOGGER = LoggerFactory.getLogger(ClientCreationView .class); 

@Autowired 
private TabSheet tabsheet; 

@Autowired 
private ClientCredentialFormular clientCredentialFormular; 

@Autowired 
private ClientRegisterFormular clientRegisterFormular; 

public ClientCreationView(){ 
    LOGGER.info("Initializing ClientCreationView..."); 
    this.setCaption("Register New Client"); 
    LOGGER.info("Initializing ClientView..."); 
    setSizeFull(); 
    setSpacing(true); 
    setMargin(true); 
    //  TabSheet tabsheet = new TabSheet(); 
    this.addComponent(tabsheet); 
    tabsheet.addTab(clientRegisterFormular); 
    tabsheet.addTab(clientCredentialFormular); 

} 

@Override 
public void enter(ViewChangeEvent event) { 
    // Do nothing... 

} 

} 

此视图的选项卡需要注入服务类:

@SpringView(name = ClientRegisterFormular.VIEW_NAME) 
@ViewScope 
public class ClientRegisterFormular extends VerticalLayout implements View { 

private static final long serialVersionUID = 1L; 
public static final String VIEW_NAME = "client_data_formular"; 
private static final Logger LOGGER = LoggerFactory.getLogger(ClientRegisterFormular.class); 

@Autowired 
IClientService clientService; 

private TextField clientIdField = new TextField("Client-Id"); 
private TextField rootUriField = new TextField("Root-URI"); 
private TextField redirectUriField = new TextField("Redirect-URI"); 
private Button saveButton = new Button("Save"); 
private Button cancelButton = new Button("Cancel"); 
private FormLayout form = new FormLayout(); 
private SaveButtonListener saveButtonListener = new SaveButtonListener(this); 
private CancelButtonListener cancelButtonListener = new CancelButtonListener(this); 


public ClientRegisterFormular(){ 
    LOGGER.info("Initializing Client Data Formular..."); 
    this.setCaption("Client Data"); 
    this.setSizeFull(); 
    this.setSpacing(true); 
    this.setMargin(true); 
    /* 
    * Panel for Formular: 
    */ 
    Panel panel = new Panel("Register Client"); 
    panel.addStyleName("regFormPanel"); 
    panel.setSizeUndefined(); // Shrink to fit content 

    //Formular: 
    this.form.setMargin(true); 
    this.form.setSizeFull(); 
    this.clientIdField.setWidth("900px"); 
    this.clientIdField.setRequiredIndicatorVisible(true); 
    form.addComponent(clientIdField); 
    this.rootUriField.setRequiredIndicatorVisible(true); 
    this.rootUriField.setWidth("900px"); 
    form.addComponent(rootUriField); 
    this.redirectUriField.setRequiredIndicatorVisible(true); 
    this.redirectUriField.setWidth("900px"); 
    form.addComponent(redirectUriField); 
    //TODO Checkboxes for 

    //Button-Layout: 
    HorizontalLayout buttonLayout = new HorizontalLayout(); 
    this.saveButton.addClickListener(saveButtonListener); 
    buttonLayout.addComponent(this.saveButton); 
    this.cancelButton.addClickListener(this.cancelButtonListener); 
    buttonLayout.addComponent(this.cancelButton); 
    buttonLayout.setComponentAlignment(this.saveButton, Alignment.TOP_LEFT); 

    form.addComponent(buttonLayout); 
    panel.setContent(form); 
    this.addComponent(panel); 
    //  this.addComponent(buttonPanel); 
    this.setComponentAlignment(panel, Alignment.TOP_LEFT); 

} 

@Override 
public void enter(ViewChangeEvent event) { 
    // Do nothing.. 

} 


private static class SaveButtonListener implements Button.ClickListener{ 

    private static final long serialVersionUID = 1L; 
    private ClientRegisterFormular clientRegisterFormular; 

    public SaveButtonListener(ClientRegisterFormular clientRegisterFormular){ 
     this.clientRegisterFormular = clientRegisterFormular; 
    } 

    @Override 
    public void buttonClick(ClickEvent event) { 
     LOGGER.info("Saving client..."); 
     Client newClient = new Client(); 
     newClient.setClientId(clientRegisterFormular.clientIdField.getValue()); 
     newClient.setRootUri(this.clientRegisterFormular.rootUriField.getValue()); 
     newClient.setRedirectUri(this.clientRegisterFormular.redirectUriField.getValue()); 
     newClient.setClientId(UUID.randomUUID().toString()); 
     this.clientRegisterFormular.clientService.createClient(newClient); 
     refreshView(); 

    } 

    public void refreshView() { 
     MainView.navigator.navigateTo(ClientManagementView.VIEW_NAME); 
    } 

} 

private static class CancelButtonListener implements Button.ClickListener{ 

    private static final long serialVersionUID = 1L; 
    private ClientRegisterFormular clientRegisterFormular; 

    public CancelButtonListener(ClientRegisterFormular clientRegisterFormular){ 
     this.clientRegisterFormular = clientRegisterFormular; 
    } 

    @Override 
    public void buttonClick(ClickEvent event) { 
     LOGGER.info("Canceling Client Creation..."); 
     refreshView(); 

    } 


    public void refreshView() { 
     MainView.navigator.navigateTo(ClientManagementView.VIEW_NAME); 
    } 

} 

} 

回答

1

我解决它。问题不在于tabsheet不是spring组件(因为我在应用程序类中声明它为@bean)。问题是我没有通过构造函数autowire。通过将tabsheet设置为构造函数的参数并在那里设置autowire,我解决了它。

0

我认为这个问题是在ClientManagementView,要在其中创建两个观点:

tabsheet.addTab(new ClientOverview()); 
tabsheet.addTab(new ClientCreationView()); 

但它应该是春季应会产生这些看法,因为你宣布他们为@SpringView和你想要注入其他豆类。

我认为你应该自动装配它们ClientManagementView:

@Autowired 
ClientOverview clientOverview; 

@Autowired 
ClientCreationView clientCreationView; 


tabsheet.addTab(clientOverview); 
tabsheet.addTab(clientCreationView); 
+0

好的,这是一个观点。我也已经尝试过,但是我得到了一个像这样的异常:org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为'clientManagementView'的bean时出错:通过字段'clientCreationView'表示的不满意的依赖关系;嵌套的异常是org.springframework.beans.factory.BeanCreationException:在文件[C:\ mypath ...]中定义的名称为'clientCreationView'的bean创建时出错:所以看起来这个链已经断了。但反正好点.P.S:我更新了我的代码 – n00bst3r

+0

以上我认为这个@Autowired 私人TabSheet标签页;可能是ClientCreationView中的一个问题。标签页是一个vaadin组件,而不是您可以自动装配的Spring组件。 –