(004)Spring Boot之SpringApplication.run为什么在不加注解的类中也可以运行,及其对比

  一般来说springBoot初始运行的类上面会加SpringBootApplication注解,但是我们发现不加注解也可以成功运行,示例如下:

  pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.edu.spring</groupId>
    <artifactId>springboot</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <name>springboot</name>
    <!-- FIXME change it to the project‘s website -->
    <url>http://www.example.com</url>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.1.6.RELEASE</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
    </dependencies>

</project>

  App.java

package com.edu.spring.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;

public class App
{
    @Bean
    Runnable createRunnable(){
        return () -> {System.out.println("spring boot is run");};
    }

    public static void main( String[] args )
    {

        ConfigurableApplicationContext context=SpringApplication.run(App.class, args);
        context.getBean(Runnable.class).run();

    }
}

   运行结果如下 :

  可以看到,springboot正常运行,并且可以创建bean,这是因为SpringApplication类中run方法,最终会调用SpringApplication的构造方法,其中传进去的参数(传的一个类)会作为源,被spring容器管理,部分源码如下:

  那么为什么我们通常还是会加SpringBootApplication注解呢?这是因为该注解包含了ComponentScan注解,以及其他注解,ComponentScan注解可以配置spring扫描的路径。所以在App.java中不加注解可以正常运行,并且创建bean,但是不会扫描到其他bean,测试如下:

  添加 User.java

package com.edu.spring.springboot;

import org.springframework.stereotype.Component;

@Component
public class User {

}

  App.java

package com.edu.spring.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;

public class App
{
    @Bean
    Runnable createRunnable(){
        return () -> {System.out.println("spring boot is run");};
    }

    public static void main( String[] args )
    {

        ConfigurableApplicationContext context=SpringApplication.run(App.class, args);
        context.getBean(Runnable.class).run();
        System.out.println(context.getBean(User.class));

    }
}

  运行结果如下:

  在App.java上面添加ComponentScan注解,可以扫描到User类

package com.edu.spring.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan
public class App
{
    @Bean
    Runnable createRunnable(){
        return () -> {System.out.println("spring boot is run");};
    }

    public static void main( String[] args )
    {

        ConfigurableApplicationContext context=SpringApplication.run(App.class, args);
        context.getBean(Runnable.class).run();
        System.out.println(context.getBean(User.class));

    }
}

  运行结果不会报错,如下:

  SpringApplication.run(App.class, args);中的App参数作为一个源,被spring容器初始化,该参数不一定是运行方法所在本身的类,可以是其他类,示例如下:

  App.java

package com.edu.spring.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;

public class App
{

    public static void main( String[] args )
    {

        ConfigurableApplicationContext context=SpringApplication.run(App2.class, args);
        context.getBean(Runnable.class).run();
        System.out.println(context.getBean(User.class));

    }
}

  App2.java

package com.edu.spring.springboot;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan
public class App2
{
    @Bean
    Runnable createRunnable(){
        return () -> {System.out.println("spring boot is run");};
    }

}

  同样可以获取Runnable和User的bean运行结果如下:

  如果此时将创建Runnable的方法写在App.java中将不会获取该bean,程序报错。因为已经指定了源是App2.java。ComponentScan扫描同一级的包,或者子包,因此要将源放在最外层的包中。源可以添加注解SpringBootApplication或者ComponentScan。

原文地址:https://www.cnblogs.com/javasl/p/11827829.html

时间: 2024-08-30 17:47:18

(004)Spring Boot之SpringApplication.run为什么在不加注解的类中也可以运行,及其对比的相关文章

Spring boot 梳理 - SpringApplication

简单启动方式 public static void main(String[] args) { SpringApplication.run(MySpringConfiguration.class, args); } 调试方式启动 java -jar myproject-0.0.1-SNAPSHOT.jar --debug 高级启动方式 @SpringBootApplication public class App { public static void main( String[] args

spring boot: spring-data-jpa (Repository/CrudRepository) 数据库操作, @Entity实体类持久化

SpringBoot实现的JPA封装了JPA的特性, Repository是封装了jpa的特性(我是这么理解的) 1在pom.xml引入mysql, spring-data-jpa依赖 2.在src/main/resource/下新建applicatoin.properties配置文件,并配置数据库连接 3.在application.properties配置jpa配置信息 4.编写实例 热部署pom.xml配置 <!-- spring boot devtools 热部署 --> <dep

【spring cloud】导入一个新的spring boot项目作为spring cloud的一个子模块微服务,怎么做/或者 每次导入一个新的spring boot项目,IDEA不识别子module,启动类无法启动/右下角没有蓝色图标

如题:导入一个新的spring boot项目作为spring cloud的一个子模块微服务,怎么做 或者说每次导入一个新的spring boot项目,IDEA不识别,启动类无法启动,怎么解决 下面一起来走一遍这个流程: 1.将一个spring boot服务导入spring cloud中作为一个子模块 如图:这里有一个现成的spring cloud微服务集群,[如何创建一个spring cloud微服务:https://www.cnblogs.com/sxdcgaq8080/p/9035724.h

【maven】【spring boot】【单元测试】 使用controller 执行单元测试类

存在这样一个场景: 当项目启动时间过长,又没办法缩短的时候,写单元测试就是一个十分耗时的工作, 这工作不在于使用编写代码,而在于每次run junit test 都需要完整启动一次项目,白白浪费宝贵的生命. 当由于某个字段没有赋值,或者某个简单判断写错,导致需要再等个3-5分钟启动 junit test,是否会想要执行一次san check? 于是乎: 假若能使用controller来调用test类方法的话,那么在本地调试单元测试时,对于一些简单的代码修改,通过热部署,只需要重新进行一次url访

Spring Boot&mdash;10ModelAndView、Model,以及@ModelAttribute注解

package com.sample.smartmap.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; i

Spring boot异常统一处理方法:@ControllerAdvice注解的使用

1.首先创建异常处理包和类 2.使用@ControllerAdvice注解,全局捕获异常类,只要作用在@RequestMapping上,所有的异常都会被捕获 package com.example.demo.exception; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; impor

idea启动spring boot无法加载或找不到主类

问题产生原因:moudle名称修改,导致项目启动不了 在Terminal界面中执行以下三个命令,我在执行第一个命令的时候报了一个找不到dependency的错误,把那个报错的dependency删了就好了. mvn clean compile,将项目重新编译 mvn install,打包 原文地址:https://www.cnblogs.com/huanghuanghui/p/10151580.html

Spring boot异常统一处理方法:@ControllerAdvice注解的使用、全局异常捕获、自定义异常捕获

https://www.cnblogs.com/goloving/p/9142222.html 一.全局异常 1.首先创建异常处理包和类 2.使用@ControllerAdvice注解,全局捕获异常类,只要作用在@RequestMapping上,所有的异常都会被捕获 package com.example.demo.exception; import org.springframework.web.bind.annotation.ControllerAdvice; import org.spri

Spring Boot --- 认识Spring Boot

在前面我们已经学习过Srping MVC框架,我们需要配置web.xml.spring mvc配置文件,tomcat,是不是感觉配置较为繁琐.那我们今天不妨来试试使用Spring Boot,Spring Boot让我们的Spring应用变的更轻量化.比如:你可以仅仅依靠一个Java类来运行一个Spring引用.你也可以打包你的应用为jar并通过使用java -jar来运行你的Spring Web应用. 一 Spring Boot简介 1.Spring Boot特点 开箱即用,提供各种默认配置来简