使用注释配置的弹簧控制台应用程序

2022-09-01 04:26:07

我想创建spring控制台应用程序(从命令行运行,例如:mvn exec:java -Dexec.mainClass=“package。MainClass”)。

这个应用程序是我想要有某种服务和道层。我知道如何为Web应用程序执行此操作,但我没有找到任何有关如何在控制台应用程序的情况下执行此操作的信息(可能使用Swing)。

我正在尝试创建类似的东西:

public interface SampleService {
 public String getHelloWorld();
}


@Service
public class SampleServiceImpl implements SampleService {
 public String getHelloWorld() {
  return "HelloWorld from Service!";
 }
}

public class Main {
 @Autowired
 SampleService sampleService;
 public static void main(String [] args) {
  Main main = new Main();
  main.sampleService.getHelloWorld();
 }
}

可能吗?我可以在某处找到如何做到这一点的例子吗?


答案 1

查看 Spring 参考 3.2.2 实例化容器

为了在控制台应用程序中使用Spring,您需要创建一个实例并从中获取Spring管理的Bean。ApplicationContext

参考中介绍了使用 XML 配置创建上下文。对于完全基于注释的方法,您可以执行如下操作:

@Component // Main is a Spring-managed bean too, since it have @Autowired property
public class Main {
    @Autowired SampleService sampleService;
    public static void main(String [] args) {
        ApplicationContext ctx = 
            new AnnotationConfigApplicationContext("package"); // Use annotated beans from the specified package

        Main main = ctx.getBean(Main.class);
        main.sampleService.getHelloWorld();
    }
}

答案 2

Spring Reference 建议在方法中使用 ClassPathXmlApplicationContext 来创建应用程序上下文,然后调用该方法以从应用程序上下文中获取对 Bean 的初始引用。在编写了几次相同的代码之后,您最终将样板重构为以下实用程序类:maingetBean

/**
 * Bootstraps Spring-managed beans into an application. How to use:
 * <ul>
 * <li>Create application context XML configuration files and put them where
 * they can be loaded as class path resources. The configuration must include
 * the {@code <context:annotation-config/>} element to enable annotation-based
 * configuration, or the {@code <context:component-scan base-package="..."/>}
 * element to also detect bean definitions from annotated classes.
 * <li>Create a "main" class that will receive references to Spring-managed
 * beans. Add the {@code @Autowired} annotation to any properties you want to be
 * injected with beans from the application context.
 * <li>In your application {@code main} method, create an
 * {@link ApplicationContextLoader} instance, and call the {@link #load} method
 * with the "main" object and the configuration file locations as parameters.
 * </ul>
 */
public class ApplicationContextLoader {

    protected ConfigurableApplicationContext applicationContext;

    public ConfigurableApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * Loads application context. Override this method to change how the
     * application context is loaded.
     * 
     * @param configLocations
     *            configuration file locations
     */
    protected void loadApplicationContext(String... configLocations) {
        applicationContext = new ClassPathXmlApplicationContext(
                configLocations);
        applicationContext.registerShutdownHook();
    }

    /**
     * Injects dependencies into the object. Override this method if you need
     * full control over how dependencies are injected.
     * 
     * @param main
     *            object to inject dependencies into
     */
    protected void injectDependencies(Object main) {
        getApplicationContext().getBeanFactory().autowireBeanProperties(
                main, AutowireCapableBeanFactory.AUTOWIRE_NO, false);
    }

    /**
     * Loads application context, then injects dependencies into the object.
     * 
     * @param main
     *            object to inject dependencies into
     * @param configLocations
     *            configuration file locations
     */
    public void load(Object main, String... configLocations) {
        loadApplicationContext(configLocations);
        injectDependencies(main);
    }
}

在应用程序 main 方法中调用该方法。请注意,该类不是 Spring 创建的 Bean,但您可以从应用程序上下文中为其属性注入一个 Bean。loadMain

public class Main {
    @Autowired
    private SampleService sampleService;

    public static void main(String[] args) {
        Main main = new Main();
        new ApplicationContextLoader().load(main, "applicationContext.xml");
        main.sampleService.getHelloWorld();
    }
}

推荐