Spring:在主方法中获取Bean失败

时间:2016-06-25 13:38:21

标签: java spring

我对Java和Spring Framework都很陌生。所以这是我构建的第一个Spring App,我遇到了自动装配我的豆子的问题。

我的Application.java:

@SpringBootApplication
public class Application {

public static void main(String[] args) throws Exception {
    SpringApplicationBuilder builder = new SpringApplicationBuilder(Application.class);
    builder.headless(false);
    ConfigurableApplicationContext ctx = builder.run(args);
    AppRepository oAppRepo = ctx.getBean(AppRepository.class);
    // Check the SystemTray is supported
    if (!SystemTray.isSupported()) {
        System.out.println("SystemTray is not supported");
        return;
    }
    CustomTray oTray = ctx.getBean(CustomTray.class);
    }
}

我在ressource文件夹中的config.xml:

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

<context:property-placeholder location="classpath:/application.properties"/>
<context:component-scan base-package="app"/>
<import resource="beans/*.xml" />
</beans>

我的beans / tray.xml:

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

<bean id="customTray" class="app.CustomTray">
    <property name="schedulerThread" value="app.SchedulerThread"></property>
    <property name="commandControlInterface" value="app.CommandControlInterface"></property>
</bean>
</beans>

我在启动时遇到的错误消息:

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [app.CustomTray] is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:371)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:331)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:968)
at app.Application.main(Application.java:46)

所以我不明白为什么没有合格的Bean因为我在tray.xml中注册了bean。 CustomTray类派生自TrayIcon类,并且创建TrayIcon没什么特别的,但是为了完成, 我的CustomTray:

public class CustomTray extends TrayIcon {

private static final String IMAGE_PATH = "/images/icon.png";
private static final String TOOLTIP = "Test";

private PopupMenu popup;
private SystemTray tray;
@Autowired private AppRepository oAppRepo;

public CustomTray() {
    super(createImage(IMAGE_PATH, TOOLTIP), TOOLTIP);
    popup = new PopupMenu();
    tray = SystemTray.getSystemTray();
    try {
        this.setup();
    } catch (AWTException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

@PostConstruct
private void setup() throws AWTException {

}

protected static Image createImage(String path, String description) {
    URL imageURL = CustomTray.class.getResource(path);
    if (imageURL == null) {
        System.err.println("Failed Creating Image. Resource not found: " + path);
        return null;
    } else {
        return new ImageIcon(imageURL, description).getImage();
    }
    }
}

之前我运行了App,没有使用Autowiring和Beans,但现在我想重构并设置一个干净的Spring App,我希望有人知道我做错了什么。

编辑: 好的,如果我使用UUID提到的注释导入xml-Files,我会收到另一条错误消息。 bean customTray有两个属性,SchedulerThread属性也应该是Singleton Bean。它在beans / scheduler.xml中声明,它本身也有一个属于bean的属性。那样:

scheduler.xml

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

    <bean id="schedulerThread" class="app.SchedulerThread">
        <property name="processManager" value="app.ProcessManager"></property>
    </bean>
</beans>

错误:

Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.String' to required type 'app.ProcessManager' for property 'processManager'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [app.ProcessManager] for property 'processManager': no matching editors or conversion strategy found

连接这些类并创建Bean的最佳方法是什么?正如我所说,我是Spring的新手,我认为我并不了解它使用豆子和自动装配的方式。

2 个答案:

答案 0 :(得分:1)

在SpringBoot应用程序中,您需要使用ImportResource注释

指定资源
@ImportResource(locations = { "classpath:config.xml", "beans/tray.xml" })

Spring Boot documentation - XML configuration

您可以使用

获取bean名称
Arrays.stream(ctx.getBeanDefinitionNames()).forEach(System.out::println);

答案 1 :(得分:0)

对我来说,解决方案是删除XML-Config文件并创建一个AppConfig-File,现在我的Application.java看起来像这样:

    @SpringBootApplication
    public class Application {
        public static void main(String[] args) {
            SpringApplicationBuilder builder = new SpringApplicationBuilder(Application.class);
            builder.headless(false);
            builder.run(args);
        }
    }

和AppConfig这样:

    @Configuration
    public class AppConfig {
        @Autowired
        GridFsTemplate gridFSTemplate;

        @Autowired
        AppRepository appRepository;

        @Autowired
        UserRepository userRepository;

        @Bean
        ProcessManager processManager() {
            return new ProcessManager();
        }

        @Bean
        SchedulerService schedulerService() {
            SchedulerService schedulerService = new SchedulerService();
            SchedulerService.setProcessManager(processManager());
            SchedulerService.start();
            return schedulerService;
        }

        @Bean
        CustomTray customTray() {
            if (!SystemTray.isSupported()) {
                System.out.println("SystemTray is not supported");
                return null;
            }
            CustomTray customTray = new CustomTray();
            customTray.setSchedulerService(schedulerService());
            customTray.setAppRepository(this.appRepository);
            try {
                customTray.setup();
            } catch (AWTException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return customTray;
        }

        @Bean
        GridFSController gridFSController() {
            GridFSController gridFSController = new GridFSController();
            return gridFSController;
        }
    }

现在我可以使用Autowired注释访问所有这些Bean,并且我不需要context.getBean()。它减少了很多代码,我认为它是更清晰的解决方案。