Spring boot 创建SpringBoot独立应用程序

Spring boot 创建SpringBoot独立应用程序,spring-boot,Spring Boot,我正试图找出如何构建Spring Boot独立应用程序。当然,自动连接需要一些初始上下文起点。如果我只是尝试自动连接一个类来运行一个作业,那么即使我将其设置为静态,它也是空的 有没有办法在独立的非web应用程序中使用Spring@Services @SpringBootApplication public class MyApplication { @Autowired private static JobRunnerService job; public stati

我正试图找出如何构建Spring Boot独立应用程序。当然,自动连接需要一些初始上下文起点。如果我只是尝试自动连接一个类来运行一个作业,那么即使我将其设置为静态,它也是空的

有没有办法在独立的非web应用程序中使用Spring@Services

@SpringBootApplication
public class MyApplication {

    @Autowired
    private static JobRunnerService job;

    public static void main(String[] args) {
         SpringApplication.run(MyApplication.class, args);

         job.send();   //job is null !

    }
}
因此,首先将静态JobRunnerService连接到运行MyApplication的主应用程序中,JobRunner(Service)类将一个非静态SshSessionService连接到其中。 SSHSSession(服务)最终只有一个无参数构造函数

@Service("jobRunnerService")
public final class JobRunner implements JobRunnerService{


    @Autowired
    private SshSessionService ssh;      

    @Autowired
     public JobRunner(SshSessionService ssh){
        this.ssh = ssh;

     }

     public void sendToAgent() { ....
}

@Service("sshSessionService")
public class SshSession implements SshSessionService {

    public SshSession() {

    }
}

它在JobRunnerService作业引用处开始时为null。

您还没有为
JobRunnerService
提供代码,但我假设它有一个默认构造函数,并且它由
@Component
注释,以便Spring在您实际自动连接它之前将其作为bean进行分析。您的
作业
为空,可能是因为它找不到
JobRunnerService
的自动连接bean,也可能是因为您没有Spring的标识符来扫描和创建类型为
JobRunnerService
的bean。您可以将
@Services
@Component
用于JobRunnerService类然后在下面添加注释
@ComponentScan(“JobRunnerService包”)
,请参见此链接:


要让独立应用正常运行,您需要执行以下几个步骤:

  • 具有
    main()
    方法的类
  • 主类的注释
  • 以及对该方法的调用

  • 如前所述,
    @springbootplication
    是一个复合注释,由
    @Configuration
    @EnableAutoConfiguration
    @ComponentScan
    组成。换句话说,它可以被后面的三个注释所取代。或者,您可以使用别名或自定义应用于组件扫描的目录


    该示例是从Spring Boot参考文档中的
    @SpringBootApplication
    段复制的(请参见上面的链接)。如果您想快速启动项目,完成构建脚本(Maven或Gradle)、依赖项等,您可以使用以下几种不同的解决方案生成项目框架:

    如果查看该方法,您会注意到它返回一个
    ApplicationContext
    。从中,您可以获取
    JobRunnerService
    ,例如

    @SpringBootApplication
    public class MyApplication {
    
        public static void main(String[] args) {
            ApplicationContext ctx = SpringApplication.run(MyApplication.class, args);
            JobRunnerService job = ctx.getBean(JobRunnerService.class);
            job.send();
        }
    }
    
    另一种解决方案是对
    send()
    方法使用注释:

    @Service("jobRunnerService")
    public class JobRunner implements JobRunnerService {
    
        @PostConstruct
        public void send() { ... }
    }
    
    然而,在您的情况下,我将实现该接口,或者作为一个单独的bean,自动连接
    JobRunnerService
    ,然后调用其
    send()
    方法

    @Component
    public class SendRunner implements ApplicationRunner {
    
        @Autowired
        private JobRunnerService job;
    
        @Override
        public void run(ApplicationArguments args) {
            job.send();
        }
    }
    
    或者让
    JobRunner
    直接实现
    ApplicationRunner
    界面:

    @Service("jobRunnerService")
    public class JobRunner implements JobRunnerService, ApplicationRunner {
    
        @Override
        public void send() { ... }
    
        @Override
        public void run(ApplicationArguments args) {
            send();
        }
    }
    

    我现在尝试以Thread/runnable的形式运行,如Spring文档3中所述。任务执行和调度

    import org.springframework.core.task.TaskExecutor;
    
    public class TaskExecutorExample {
    
    private class MessagePrinterTask implements Runnable {
    
        private String message;
    
        public MessagePrinterTask(String message) {
            this.message = message;
        }
    
        public void run() {
            System.out.println(message);
        }
    
    }
    
    private TaskExecutor taskExecutor;
    
    public TaskExecutorExample(TaskExecutor taskExecutor) {
        this.taskExecutor = taskExecutor;
    }
    
    public void printMessages() {
        for(int i = 0; i < 25; i++) {
            taskExecutor.execute(new MessagePrinterTask("Message" + i));
        }
    }
    
    导入org.springframework.core.task.TaskExecutor;
    公共类任务执行器示例{
    私有类MessagePrinterTask实现可运行{
    私有字符串消息;
    公共消息PrinterTask(字符串消息){
    this.message=消息;
    }
    公开募捐{
    System.out.println(消息);
    }
    }
    私有任务执行器任务执行器;
    公共TaskExecutor示例(TaskExecutor TaskExecutor){
    this.taskExecutor=taskExecutor;
    }
    公共消息(){
    对于(int i=0;i<25;i++){
    taskExecutor.execute(新的MessagePrinterTask(“Message”+i));
    }
    }
    
    }

    所以就我而言,我正在努力

    @Service("jobRunnerService")
    @Component
    public class JobRunner implements JobRunnerService, ApplicationRunner{
    
    @Autowired
    public TaskExecutor taskExecutor;
    
    @Autowired
    private SshSessionService ssh;
    
            private class JobTask implements Runnable{
    
                public void run(){
    
                    Boolean success = connectToAgent();
    
                    if(success){
                        log.debug("CONNECTED!!!");
                    }
    
                }
    
            }
    
    
    
    /**
     * Construct JobRunner with TaskExecutor
     * @param taskExecutor
     */
    @Autowired
    public JobRunner(TaskExecutor taskExecutor, SshSessionService ssh) {
        this.taskExecutor = taskExecutor;
        this.ssh = ssh;
    }
    
    private Map<String, String> sessionParams; 
    
    
    
    private final Logger log = LoggerFactory.getLogger(this.getClass());
    
    
    @Override
    public void run(ApplicationArguments args) {
    
        /**
         * Starting point of application
         * 
         */
        taskExecutor.execute(new JobTask());
    }
    
    @Service(“jobRunnerService”)
    @组成部分
    公共类JobRunner实现JobRunnerService、ApplicationRunner{
    @自动连线
    公共任务执行者任务执行者;
    @自动连线
    专用SshSessionService ssh;
    私有类JobTask实现Runnable{
    公开募捐{
    布尔成功=connectToAgent();
    如果(成功){
    log.debug(“已连接!!!”;
    }
    }
    }
    /**
    *使用TaskExecutor构造JobRunner
    *@param任务执行器
    */
    @自动连线
    public JobRunner(TaskExecutor TaskExecutor,SshSessionService ssh){
    this.taskExecutor=taskExecutor;
    this.ssh=ssh;
    }
    私有映射会话参数;
    私有最终记录器log=LoggerFactory.getLogger(this.getClass());
    @凌驾
    公共作废运行(应用程序参数){
    /**
    *应用起点
    * 
    */
    taskExecutor.execute(新作业任务());
    }
    
    仅获取org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到符合依赖项要求的[org.springframework.core.task.TaskExecutor]类型的bean


    如何让导入的lib被接受为TaskExecutor Bean???

    我正在做的事情有一些根本性的错误…因此componentscan将无法工作…我只是不知道如何做。Dunni是对的,静态字段上的自动连线将无法工作。我没有注意到。我已经有了这些,但在运行调用下面会发生什么在main方法中,引用我的案例job.send()中的下一个调用如果你看一下我上面的代码,你会发现初始化属于@Services的bean有问题…静态字段上的自动连接不起作用。如果你想在启动时运行一个方法,请创建一个实现CommandLineRunner或ApplicationRunner接口的bean。实现这些接口的bean由Spring Boot自动执行一旦应用程序准备就绪。邓尼是对的,@JohnnyOOMG@matsev我使用了最后一个实现建议…非常感谢!!
    @Service("jobRunnerService")
    @Component
    public class JobRunner implements JobRunnerService, ApplicationRunner{
    
    @Autowired
    public TaskExecutor taskExecutor;
    
    @Autowired
    private SshSessionService ssh;
    
            private class JobTask implements Runnable{
    
                public void run(){
    
                    Boolean success = connectToAgent();
    
                    if(success){
                        log.debug("CONNECTED!!!");
                    }
    
                }
    
            }
    
    
    
    /**
     * Construct JobRunner with TaskExecutor
     * @param taskExecutor
     */
    @Autowired
    public JobRunner(TaskExecutor taskExecutor, SshSessionService ssh) {
        this.taskExecutor = taskExecutor;
        this.ssh = ssh;
    }
    
    private Map<String, String> sessionParams; 
    
    
    
    private final Logger log = LoggerFactory.getLogger(this.getClass());
    
    
    @Override
    public void run(ApplicationArguments args) {
    
        /**
         * Starting point of application
         * 
         */
        taskExecutor.execute(new JobTask());
    }