SpringBoot main方法分析

本文介绍了Spring如何整合MyBatis,包括Spring的main方法和项目结构,然后转向SpringBoot的整合方式,展示了SpringBoot的main方法及@SpringBootApplication注解的工作原理。同时,探讨了CommandLineRunner接口的应用,以及在application.properties中的配置选项。文章最后提到了在SpringBoot中@Autowired注解的使用和main方法的其他配置选项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring整合MyBatis

在了解SpringBoot的main方法之前,先看一下Spring整合Mybatis的例子,首先对于Spring整合Mybatis,对于Spring的配置文件可以通过 .xml配置类 的形式,这里不做详细介绍。
项目结构
在这里插入图片描述Spring的main方法

public class Test {

	public static void main(String[] args) throws Exception {

		ApplicationContext context =
				new AnnotationConfigApplicationContext(MyConfig.class);

		GoodsService goodsService = context.getBean(GoodsService.class);

		Goods goods = goodsService.selectByPrimaryKey(1);
		System.out.println("查询结果:" + goods.getId() + "--" + goods.getName() + "--" + goods.getStore());
	}
}

1.第一步先启动Spring容器,new AnnotationConfigApplicationContext返回一个application容器,此时引入Spring配置类,并注入Bean对象。
2.从Spring容器中获取对应的Bean对象,对应为GoodsService对象

SpringBoot整合Mybatis

这里只是通过整合MyBatis去查看SpringBoot的main方法。对于SpringBoot取消了Spring的相关配置文件,相反都统一到了application.properties文件中,对数据库的相关端口号,进行配置。
项目结构
在这里插入图片描述

此处Application文件为项目的入口。
SpringBoot的main方法

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

上述代码为SpringBoot初始创建时的main方法,@SpringBootApplication 注解将Application设置为配置类,进入到@SpringBootApplication的源码,可以看到组合三个注解:@ComponentScan,@EnableAutoConfiguration,@SpringBootConfiguration.分析这三个注解,
此时点击查看SpringApplication底层源码。

public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
        this.configureHeadlessProperty();
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        listeners.starting();

        Collection exceptionReporters;
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            Banner printedBanner = this.printBanner(environment);
            context = this.createApplicationContext();
            exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
            this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
            this.refreshContext(context);
            this.afterRefresh(context, applicationArguments);
            stopWatch.stop();
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }

            listeners.started(context);
            this.callRunners(context, applicationArguments);
        } catch (Throwable var10) {
            this.handleRunFailure(context, var10, exceptionReporters, listeners);
            throw new IllegalStateException(var10);
        }

        try {
            listeners.running(context);
            return context;
        } catch (Throwable var9) {
            this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var9);
        }
    }

查看run方法,返回值为ConfigurableApplicationContext返回值为一个Application容器,对于main方法进行修改

@SpringBootApplication//该注解类似于配置类
public class Application  {

    public static void main(String[] args) {
        
        ApplicationContext context = SpringApplication.run(Application.class, args);

        GoodsService goodsService = context.getBean(GoodsService.class);

        Goods goods = goodsService.getGoodsById(1);
        System.out.println("产品信息:" + goods);
    }
}

这里通过ApplicationContext返回一个application容器,此时通过DEBUG调试查看context内容,在我们进行调试之前,先思考对于Application类,由于Application是一个配置类,就会有BeanDefinition去抽象信息。那么是否会生成一个Bean对象??
在这里插入图片描述
在这里插入图片描述
此时我们在BeanDefinition中查看到application
在这里插入图片描述
singletonObjects中查找到application对象,那么我们就可以在main方法中 @Autowired 自动注入可以将Service对象进行注入使用。

CommandLineRunner接口

对于Application类实现CommandLineRunner接口,有一个 **run()**方法,该方法是SpringIOC启动完成后,调用的方法。

package org.springframework.boot;

@FunctionalInterface
public interface CommandLineRunner {
    void run(String... args) throws Exception;
}
@SpringBootApplication//该注解类似于配置类
public class Application implements CommandLineRunner {

    public static void main(String[] args) {
        //启动springIOC容器
        ApplicationContext context = SpringApplication.run(Application.class, args);

        GoodsService goodsService = context.getBean(GoodsService.class);

        Goods goods = goodsService.getGoodsById(1);
        System.out.println("产品信息:" + goods);
    }

    @Override
    public void run(String... args) throws Exception {//CommandLineRunner接口实现的方法
        System.out.println("这是springIOC启动完成后 调用的方法");
    }
}

对于main方法的其他配置。

#关闭启动logo
#spring.main.banner-mode=off
#设置定义配置类的路径 也即是入口路径
#spring.main.sources= //application.class的文件路径
#生成的bean对象是否覆盖
#spring.main.allow-bean-definition-overriding=true

若在application.properties文件中设置了 #spring.main.sources 在main方法中

@SpringBootApplication//该注解类似于配置类
public class Application implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication();
        ApplicationContext context1 = app.run(args);
        GoodsService goodsService = context1.getBean(GoodsService.class);
        Goods goods = goodsService.getGoodsById(1);
        System.out.println("产品信息:" + goods);

    }
 }
### 如何调试 Spring Boot `main` 方法 为了有效调试 Spring Boot 应用程序中的 `main` 方法,开发者可以采用多种策略和技术来确保应用程序按预期运行并解决问题。以下是几种常见的调试方法: #### 使用 IDE 调试工具 集成开发环境(IDE),如 IntelliJ IDEA 或 Eclipse 提供强大的内置调试功能。通过设置断点,在 `main` 方法内暂停执行流程,逐步检查变量状态和逻辑走向。 ```java @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); // 设置断点在此处以监控启动过程 } } ``` 当在上述位置设置了断点之后,可以通过点击 IDE 中的“Debug”按钮而不是普通的“Run”,从而进入调试模式[^1]。 #### 日志记录增强 利用日志框架(例如 Logback 或 SLF4J)增加详细的日志输出可以帮助理解应用的行为。可以在 `application.properties` 文件中调整日志级别以便获取更多诊断信息。 ```properties logging.level.org.springframework=DEBUG ``` 这会使得 Spring 框架内部的日志更加详尽,有助于发现潜在问题所在[^2]。 #### 命令行参数辅助 向 `main` 函数传入特定命令行参数能够改变应用程序行为或提供额外的信息支持。比如使用 `-Xdebug` 参数开启远程调试端口连接外部调试器;或者自定义一些开关型参数控制某些特性是否激活。 ```bash java -jar myapp.jar --spring.profiles.active=dev ``` 此命令指定了活动配置文件为 dev,这对于多环境部署非常有用[^3]。 #### 利用条件注解排查依赖注入失败 如果遇到因 Bean 定义冲突或其他原因导致的应用无法正常初始化的情况,则可借助于像 `@ConditionalOnMissingBean` 这样的条件注解读取上下文中是否存在指定类型的 bean 来帮助定位错误根源。 ```java @Bean @ConditionalOnMissingBean public MyService myService() { return new MyServiceImpl(); } ``` 这种方法能有效地防止重复注册相同服务实例的同时也便于追踪哪些组件被成功加载进了容器里。 #### 性能分析与内存泄漏检测 对于更复杂的问题,还可以引入专业的性能剖析工具(Profiler)。这些工具有助于识别长时间运行的任务、高资源消耗的操作以及可能存在的内存泄露等问题。常见选项包括 VisualVM 和 JProfiler 等。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值