2014-11-26 3 views
1

Мой главный класс: package net.draconia;Autowiring основной класс в Swing/Spring App

import java.io.Serializable; 

import javax.swing.SwingUtilities; 
import javax.swing.UIManager; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.ConfigurableApplicationContext; 
import org.springframework.context.support.ClassPathXmlApplicationContext; 
import org.springframework.stereotype.Component; 

import net.draconia.apigenerator.ui.APIGeneratorFrame; 

public class APIGenerator implements Runnable, Serializable 
{ 
    private static final long serialVersionUID = 3837819659124519652L; 

    @Autowired 
    private APIGeneratorFrame mWndView; 

    public APIGenerator() 
    { } 

    protected APIGeneratorFrame getView() 
    { 
     return(mWndView); 
    } 

    public void run() 
    { 
     try 
      { 
      UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); 

      getView().setVisible(true); 
      } 
     catch(Exception objException) 
      { 
      objException.printStackTrace(System.err); 
      } 
    } 

    public static void main(final String[] sArrArgs) 
    { 
     ApplicationContext objContext = new ClassPathXmlApplicationContext("application-context.xml"); 

     try 
      { 
      ((ConfigurableApplicationContext)(objContext)).registerShutdownHook(); 

      APIGenerator objGenerator = ((APIGenerator)(objContext.getBean("app"))); 

      SwingUtilities.invokeLater(objGenerator); 
      } 
     finally 
      { 
      ((ConfigurableApplicationContext)(objContext)).close(); 
      } 
    } 
} 

Для всех намерений и целей, давайте предположим, что APIGeneratorFrame просто:

public class APIGeneratorFrame extends JFrame 
{ } 

Моя упрощенным приложение-context.xml является:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:util="http://www.springframework.org/schema/util" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd 
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd 
         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd"> 

    <bean class="net.draconia.apigenerator.ui.APIGeneratorFrame" /> 

    <bean class="net.draconia.APIGenerator" id="app" /> 
</beans> 

Когда я запустить приложение, хотя - я получаю null для представления. Я занимаюсь Spring в течение нескольких лет, а в прошлом я использовал ленивое создание (если (mWndView == null) mWndView = ... return mWndView) или сделал геттеры и сеттеры для представления публичными и добавил ссылки внутри application-context - оба из них заставили меня обойти эту проблему, но я стараюсь, чтобы этот проект больше полагался на весну, и нет никакой причины сделать публикацию View открытой, поскольку ее никогда не следует публично публиковать за пределами основного класса, который больше трамплина к главному событию.

Что я могу делать не так, что View не автоподключен? Как вы можете видеть, я захватываю основное приложение из файла контекста приложения, поэтому он управляется весной. Я не тестировал класс View, но сейчас все, что он содержит, является меткой и списком, даже не получающим доступа к ним, но автоматически и автоматически определяемым в файле контекста приложения. При необходимости я могу включить более полный контекст приложения и/или класс APIGeneratorFrame. Я попытался включить только самое простое, хотя на данный момент. Есть предположения?

+0

Autowiring main class -> Звучит ужасно :) – Maksym

+0

Почему? Остальное авто. Spring заботится об определении того, создан ли какой-либо требуемый компонент или что-то еще, убедитесь, что он не равен нулю. В общем, это уменьшает размер методов - я мог бы потенциально разбить основной класс на основной класс и контроллер, но я всегда совмещал их 2, и контроллер имел бы представление в нем - это решило бы мою проблему I ' m ** почти ** some –

ответ

2

Вы пытались предоставить представление bean id?

<bean id="mWndView" class="net.draconia.apigenerator.ui.APIGeneratorFrame" /> 

Дальнейшие замечания:

@Autowired является Spring конкретных аннотаций, тем более общий один @Inject.

Возврат (mWndView); операторам не нужны скобки.

Вы можете использовать компонент сканирования тега из «http://www.springframework.org/schema/context» вместо ручной проводки:

<context:component-scan base-package="net.draconia" /> 

Чтобы использовать компонент-сканирование можно опустить фасоль в текущем контексте и добавить @Component аннотаций на классы.

+0

Я не нашел ничего, что говорило бы мне, что именно @Component делает вне настройки Spring-MVC - что он делает? С момента публикации я попытался добавить идентификатор, а также отделить интерфейс контроллера от основного класса - просто переместил NPE в класс Controller, а не автоматически открыл его. Что значит опустить бобы в текущем контексте? Как Spring знал, что отправлять конструкторам и устанавливать значения свойств? –

+0

Просто попробовал @Component и удалил хотя бы App, Controller и View и получил ошибку, из-за которой не было найдено ни одного компонента с именем controller. Я не уверен в том, как получить компонент и запустить Spring без ApplicationContext.getBean (.. ,) –

+0

Хорошо, я выполнил компонентное сканирование - сначала, потому что у меня были компоненты, он сказал, что есть дублированные варианты для beans для autowire - удалены аннотации @Component, и он запущен без сучка и задоринки - Спасибо Адриаан - я положил checkmark - я бы повысил его, но это не позволило мне сказать, что мне нужна репутация 15 - я не ответил на многие вопросы здесь, но спасибо вам большое! –

Смежные вопросы