Migrates a Spring MVC application to Spring Boot, converting XML config to auto-configuration, restructuring the project, and replacing container deployment with embedded. Use when modernizing a legacy Spring app, when moving off a standalone servlet container, or when the user has web.xml and wants application.yml.
77
96%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Spring Boot is Spring MVC with conventions, embedded server, and auto-configuration. The migration isn't a rewrite — it's deleting XML and letting Boot infer it.
| Concern | Spring MVC (classic) | Spring Boot | Migration effort |
|---|---|---|---|
@Controller classes | @Controller, @RequestMapping | Same — unchanged | Zero |
@Service, @Repository | Same annotations | Same — unchanged | Zero |
| Bean wiring (XML) | <bean id=... class=...> | @Configuration + @Bean, or just @Component | High — this is the work |
| DispatcherServlet setup | web.xml | Auto-configured — delete it | Delete |
| Server | Deploy WAR to Tomcat | Embedded Tomcat — java -jar | pom.xml change |
| Properties | Multiple .properties via <context:property-placeholder> | application.yml with profiles | Consolidate |
| View resolver | <bean class="InternalResourceViewResolver"> | spring.mvc.view.prefix=... property | One-liner |
| Static resources | <mvc:resources mapping=...> | /static, /public auto-served | Move files |
Boot can coexist with XML config. Migrate incrementally:
@Configuration. Test. Repeat.web.xml once DispatcherServlet XML config is gone.Maven:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.x.x</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Keep existing deps; remove spring-webmvc, spring-context — the starter brings them -->
</dependencies>Remove explicit spring-* versions — let the parent BOM manage them. Version conflicts here are → dependency-resolver territory.
@SpringBootApplication
@ImportResource("classpath:applicationContext.xml") // bridge — delete later
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}@ImportResource lets Boot load your old XML. App runs under Boot with zero config migrated. Verify everything works before touching XML.
XML:
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="url" value="${db.url}"/>
<property name="username" value="${db.user}"/>
</bean>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource"/>
</bean>Boot — option A: explicit @Configuration:
@Configuration
public class DatabaseConfig {
@Bean
public DataSource dataSource(@Value("${db.url}") String url,
@Value("${db.user}") String user) {
BasicDataSource ds = new BasicDataSource();
ds.setUrl(url);
ds.setUsername(user);
return ds;
}
// txManager — Boot auto-configures DataSourceTransactionManager if a DataSource bean exists. DELETE.
}Boot — option B: auto-config (preferred when it applies):
# application.yml
spring:
datasource:
url: ${DB_URL}
username: ${DB_USER}No Java at all. spring-boot-starter-jdbc sees these properties, auto-configures Hikari (not DBCP — behavior change, flag it).
| XML | Boot |
|---|---|
<context:component-scan base-package=...> | @SpringBootApplication scans its own package + subpackages. If your packages are elsewhere: @ComponentScan(basePackages=...) |
<mvc:annotation-driven/> | Auto — delete |
<mvc:resources mapping="/static/**" location="/assets/"/> | Move files to src/main/resources/static/ |
<bean class="...ViewResolver"> | spring.mvc.view.prefix / .suffix properties |
<tx:annotation-driven/> | Auto — @Transactional just works |
<context:property-placeholder location=...> | application.yml + @Value or @ConfigurationProperties |
Filters in web.xml | @Bean FilterRegistrationBean<YourFilter> or just @Component on the filter |
Servlets in web.xml | @Bean ServletRegistrationBean<...> |
Once every <bean> is migrated: delete @ImportResource, delete applicationContext.xml, delete web.xml. Run tests.
| Gotcha | Symptom | Fix |
|---|---|---|
| Package layout | Beans not found | @SpringBootApplication scans its own package down — move main class up, or add @ComponentScan |
| Auto-config conflict | Two DataSource beans | Your XML defined one, Boot auto-configured another. @Primary, or exclude the auto-config: @SpringBootApplication(exclude=DataSourceAutoConfiguration.class) |
| Connection pool switch | Different perf characteristics | Boot defaults to Hikari. If you need DBCP, declare it explicitly. |
| Context path | URLs all 404 | Was /myapp in the servlet container; now /. Set server.servlet.context-path=/myapp or fix your links. |
| JSP | Whitelabel error page | JSP + embedded Tomcat is fiddly — spring-boot-starter-tomcat provided scope, tomcat-embed-jasper, and keep WAR packaging. Or migrate to Thymeleaf. |
@ImportResource exists so you can do it a bean at a time.javax.* → jakarta.*). Do MVC → Boot 2, then Boot 2 → 3.## Current state
Spring version: <x>
Config style: <XML | JavaConfig | mixed>
Packaging: <WAR on <container>>
## Target
Boot version: <x>
Packaging: <executable JAR>
## Migration steps
| Step | XML removed | Java/YAML added | Test checkpoint |
| ---- | ----------- | --------------- | --------------- |
## Behavior changes
<connection pool, context path, anything auto-config does differently — FLAG THESE>
## Files
### pom.xml (diff)
### Application.java (new)
### application.yml (new)
### Deleted: <web.xml, applicationContext.xml, ...>47d56bb
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.