spring-boot-starter-parent as the parent POM.spring-boot-starter (runtime) and spring-boot-starter-test (test scope).@Bean, singleton scope behavior, and Logback profile-based configuration.spring-boot-starter-parent gives you managed dependency versions, plugin defaults, and resource filtering — no version declarations needed for standard starters.spring-boot-maven-plugin packages the app as an executable fat JAR.<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>4.0.6</version> </parent> <properties> <java.version>21</java.version> </properties>
@SpringBootApplication@SpringBootConfiguration, @EnableAutoConfiguration, and @ComponentScan.ApplicationContextSpringApplication.run() returns the ApplicationContext — hold onto it to query beans programmatically.ApplicationContext ctx = SpringApplication.run(MtitekSpringStarterProjectApplication.class, args);
// Dump all registered bean names
Arrays.stream(ctx.getBeanDefinitionNames())
.sorted()
.forEach(bdn -> LOG.info("Spring Bean Definition Name: {}", bdn));
ctx.getBean(MyClass.class)) or by name + type (ctx.getBean("beanName", MyClass.class)).@SpringBootApplication class is the camel-case simple class name — e.g. MtitekSpringStarterProjectApplication → "mtitekSpringStarterProjectApplication".// Retrieve by type
MtitekSpringStarterProjectApplication app = ctx.getBean(MtitekSpringStarterProjectApplication.class);
app.setValue(2);
// Retrieve by name — same instance, value is still 2
app = ctx.getBean("mtitekSpringStarterProjectApplication",
MtitekSpringStarterProjectApplication.class);
System.out.println(app.getValue()); // prints 2
@Bean"appUuid".@Bean is declared inside the @SpringBootApplication class, which carries @SpringBootConfiguration (a form of @Configuration) — the method runs in full mode (CGLIB proxy), so the singleton contract is enforced by Spring.@Bean
String appUuid() {
return UUID.randomUUID().toString();
}
// Retrieve the bean by name and type
String uuid = ctx.getBean("appUuid", String.class);
Note: Registering a plain String bean is valid but can cause ambiguity if multiple String beans exist. Always retrieve it by name in that case.
application.yml — Maindev — controls which <springProfile> block in logback-spring.xml is activated at runtime.application.yml via logging.level.* — the commented-out block in the project shows the equivalent YAML syntax.spring:
application:
name: mtitek-spring-starter-project
profiles:
active: dev
application.yml — Testapplication.yml activates the prod profile during test runs.spring:
application:
name: mtitek-spring-starter-project
profiles:
active: prod
logback-spring.xml vs logback.xmllogback-spring.xml (not logback.xml) to unlock Spring Boot extensions — specifically the <springProfile> element for profile-based log config.logback.xml, Spring Boot has no chance to customize initialization — <springProfile> is silently ignored../logs/mtitek-spring-starter-project.log, rolling on size (10MB) and daily, archived under ./logs/archived/.AsyncAppender — writes are enqueued off the main thread, reducing I/O latency impact on throughput.<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender"> <appender-ref ref="FILE" /> </appender>
com.mtitek.spring at INFO, root at INFO.com.mtitek.spring at INFO to ASYNC_FILE only; root at WARN — only warnings and errors from third-party libraries are captured.additivity="false" on the package logger prevents log events from bubbling up to the root logger, avoiding duplicate output.<springProfile name="dev">
<logger name="com.mtitek.spring" level="INFO" additivity="false">
<appender-ref ref="CONSOLE" />
<appender-ref ref="ASYNC_FILE" />
</logger>
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="ASYNC_FILE" />
</root>
</springProfile>
<springProfile name="prod">
<logger name="com.mtitek.spring" level="INFO" additivity="false">
<appender-ref ref="ASYNC_FILE" />
</logger>
<root level="WARN">
<appender-ref ref="ASYNC_FILE" />
</root>
</springProfile>
src/test/resources/logback-test.xml)src/test/resources — takes precedence over logback-spring.xml.@SpringBootTest boots the full application context for each test run.contextLoads() test is a smoke test — it passes if and only if the context starts without errors.prod (set in src/test/resources/application.yml) — file logging suppressed, root level WARN.@SpringBootTest
class MtitekSpringStarterProjectApplicationTests {
@Test
void contextLoads() { }
}
main() in MtitekSpringStarterProjectApplication.mvn spring-boot:runmvn clean package java -jar target/mtitek-spring-starter-project-0.0.1-SNAPSHOT.jar
java -jar target/mtitek-spring-starter-project-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod
The ./logs directory is created relative to the working directory at runtime — not relative to the JAR location.
Adjust LOG_PATH in logback-spring.xml or pass -DLOG_PATH=/LOG_PATH as a JVM argument for deployments.