{"id":7636,"date":"2021-09-26T07:20:48","date_gmt":"2021-09-26T11:20:48","guid":{"rendered":"https:\/\/springframework.guru\/?p=7636"},"modified":"2022-02-04T12:30:05","modified_gmt":"2022-02-04T17:30:05","slug":"bootstrapping-data-in-spring-boot","status":"publish","type":"post","link":"https:\/\/springframework.guru\/bootstrapping-data-in-spring-boot\/","title":{"rendered":"Bootstrapping Data in Spring Boot"},"content":{"rendered":"<p>While developing a Spring Boot Application, sometimes we need to run a piece of code at startup. This code can be anything. You might want to log certain information or run some cron jobs or send some notifications. Or you might even want to start the application with seed data in the database.<\/p>\n<p>In this post, We will take a look at different approaches to bootstrap a Spring Boot application during startup.<\/p>\n<h2>Bootstrapping with Spring Boot<\/h2>\n<p>Spring Boot offers different ways to execute logic on startup. One of the common ways is to use the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">CommandLineRunner<\/code> Interface.<\/p>\n<h2>Using CommandLineRunner<\/h2>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">CommandLineRunner<\/code> is an interface used to indicate that a bean should run when it is contained within a SpringApplication.<\/p>\n<p>In this example code, I will create a domain object to model meme creaters. I will use the embedded <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">H2<\/code> database for the demo.<\/p>\n<h2>Maven Dependency<\/h2>\n<p>For this demo, you need the following core dependencies in your <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">pom.xml<\/code> file.<\/p>\n<p><strong>pom.xml<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"xml\">\t&lt;dependency&gt;\r\n\t    &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\r\n            lt;artifactId&gt;spring-boot-starter-web&lt;\/artifactId&gt;\r\n        &lt;\/dependency&gt;\r\n\r\n       &lt;dependency&gt;\r\n            &lt;groupId&gt;com.h2database&lt;\/groupId&gt;\r\n            &lt;artifactId&gt;h2&lt;\/artifactId&gt;\r\n            &lt;scope&gt;runtime&lt;\/scope&gt;\r\n        &lt;\/dependency&gt;\r\n\r\n        &lt;dependency&gt;\r\n            &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\r\n            &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;\/artifactId&gt;\r\n        &lt;\/dependency&gt;\r\n        &lt;dependency&gt;\r\n           &lt;groupId&gt;org.projectlombok&lt;\/groupId&gt;\r\n             &lt;artifactId&gt;lombok&lt;\/artifactId&gt;\r\n              &lt;scope&gt;provided&lt;\/scope&gt;\r\n\t&lt;\/dependency&gt;\r\n<\/pre>\n<p><strong>The Domain Class<\/strong><\/p>\n<p>The code of the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">MemeMaker<\/code> domain class is this.<\/p>\n<p><strong>MemeMaker.java<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">@Entity\r\n@Table(name = \"memes\")\r\n@Getter\r\n@Setter\r\npublic class MemeMaker {\r\n\r\n    @Id\r\n    @GeneratedValue(strategy = GenerationType.AUTO)\r\n    private int memeId;\r\n    private String memeMaker;\r\n    private String memeLevel;\r\n    private String memeCategory;\r\n\r\n    public MemeMaker() {\r\n    }\r\n\r\n    public MemeMaker(String memeMaker, String memeLevel, String memeCategory) {\r\n        this.memeMaker = memeMaker;\r\n        this.memeLevel = memeLevel;\r\n        this.memeCategory = memeCategory;\r\n    }\r\n}\r\n<\/pre>\n<p>The preceding code uses <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">Lombok<\/code> to reduce boilerplate code. If you are new to <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">Lombok<\/code>, I suggest going through my post on <a href=\"https:\/\/springframework.guru\/spring-boot-with-lombok-part-1\/\">Lombok<\/a>.<\/p>\n<p>The code of the Repository Interface is this.<\/p>\n<p><strong>MemeRepository<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">@Repository\r\npublic interface MemeRepository extends CrudRepository&lt;MemeMaker, Integer&gt; {\r\n}\r\n<\/pre>\n<p>The configuration properties for H2 in-memory database is set in the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">application.properties<\/code> file.<\/p>\n<p><strong>application.properties<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">spring.h2.console.enabled=true\r\nspring.datasource.url=jdbc:h2:mem:memedb\r\n<\/pre>\n<p>The h2 console is set to true in Line 1 which enables the h2-console view in the browser, and the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">datasource.url<\/code> is set to <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">jdbc:h2:mem:memedb<\/code> where <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">memedb<\/code> is the set database name.<\/p>\n<p>The code for <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BootstrapCommandLineRunner<\/code> class, that bootstraps the application with seed data, is this.<\/p>\n<p><strong>BootstrapCommandLineRunner.java<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">@Component\r\npublic class BootstrapCommandLineRunner implements CommandLineRunner {\r\n\r\n    private MemeRepository memeRepository;\r\n\r\n    @Autowired\r\n    public BootstrapCommandLineRunner(MemeRepository memeRepository) {\r\n        this.memeRepository = memeRepository;\r\n    }\r\n\r\n    @Override\r\n    public void run(String... args) throws Exception {\r\n\r\n        memeRepository.save(new MemeMaker(\"Alex\",\"Novice\", \"Sports\"));\r\n        memeRepository.save(new MemeMaker(\"John\",\"OG\", \"Wholesome\"));\r\n        memeRepository.findAll().forEach((meme) -&gt; {\r\n        });\r\n    }\r\n}\r\n<\/pre>\n<p>The preceding code annotates the class with <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Component<\/code> so that Spring detects it during component scanning. When you start the application, the overriden <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">run()<\/code> method will execute.<\/p>\n<p>With the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Autowired<\/code> annotation in Line 6, we inject the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">MemeRepository<\/code> bean into the repository field.<\/p>\n<p>The <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">run()<\/code> method uses the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Autowired<\/code> \u00a0<code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">MemeRepository<\/code>\u00a0to create two <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">Meme<\/code> objects and stores them in the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">H2<\/code> database.<\/p>\n<p><strong>Note<\/strong>: A Spring Boot application can have multiple beans implementing <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">CommandLineRunner<\/code>. These can be ordered with <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Order<\/code> annotation.<\/p>\n<h2>Bootstrapping with Spring Framework<\/h2>\n<p>The Spring Framework provides the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">ApplicationListener<\/code> interface that allows you to tap into various events of the framework. One such event that you can handle to bootstrap data is <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">ContextRefreshedEvent<\/code>.<\/p>\n<p>The following code shows how to use the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">ApplicationListener<\/code> interface.<\/p>\n<p><strong>BootstrapApplicationListener.java<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">@Component\r\npublic class BootstrapApplicationListener implements ApplicationListener {\r\n\r\n    private MemeRepository memeRepository;\r\n\r\n    @Autowired\r\n    public BootstrapApplicationListener(MemeRepository memeRepository) {\r\n        this.memeRepository = memeRepository;\r\n    }\r\n\r\n    @Override\r\n    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {\r\n        memeRepository.save(new MemeMaker(\"Bob\",\"Noobie\", \"Horror\"));\r\n        memeRepository.save(new MemeMaker(\"Hitman\",\"OG\", \"Global\"));\r\n\r\n    }\r\n}\r\n<\/pre>\n<p>The preceding code overrides the overloaded <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent)<\/code>\u00a0 method of <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">ApplicationListener<\/code>. Inside this method, the code uses the autowired repository to create and save two Memes objects.<\/p>\n<h2>Console Output<\/h2>\n<p>After you login to the H2 database on the URL <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">localhost:8080\/h2-console<\/code> using the JDBC URL set in <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">application.properties<\/code>, you will see the following output.<\/p>\n<p><a href=\"http:\/\/springframework.guru\/wp-content\/uploads\/2021\/09\/2021-12-18-4.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-7705\" src=\"http:\/\/springframework.guru\/wp-content\/uploads\/2021\/09\/2021-12-18-4-1024x576.png\" alt=\"\" width=\"1024\" height=\"576\" srcset=\"https:\/\/springframework.guru\/wp-content\/uploads\/2021\/09\/2021-12-18-4-1024x576.png 1024w, https:\/\/springframework.guru\/wp-content\/uploads\/2021\/09\/2021-12-18-4-300x169.png 300w, https:\/\/springframework.guru\/wp-content\/uploads\/2021\/09\/2021-12-18-4-768x432.png 768w, https:\/\/springframework.guru\/wp-content\/uploads\/2021\/09\/2021-12-18-4-1536x864.png 1536w, https:\/\/springframework.guru\/wp-content\/uploads\/2021\/09\/2021-12-18-4-848x477.png 848w, https:\/\/springframework.guru\/wp-content\/uploads\/2021\/09\/2021-12-18-4-410x231.png 410w, https:\/\/springframework.guru\/wp-content\/uploads\/2021\/09\/2021-12-18-4.png 1920w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/p>\n<h2>Summary<\/h2>\n<p>In addition to the most common bootstrapping approaches I have shown, there are also other ways to do the same thing. One is using the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@PostConstruct<\/code> annotation. Another is to use <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">ApplicationRunner<\/code> instead of <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">CommandLineRunner<\/code>. Although both are different ways to do the same things, they are different based on what the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">run()<\/code> method accepts. The <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">run()<\/code> method of <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">CommandLineRunner<\/code> accepts raw Strings. On the other hand, <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">ApplicationRunner<\/code> accepts an instance of <code>ApplicationArguments<\/code>\u00a0so that you can access the bootstrap arguments passed when initializing the application.<\/p>\n<p>You can find the source code of this post here on <a href=\"https:\/\/github.com\/spring-framework-guru\/sfg-blog-posts\/tree\/master\/bootstrapping-data-in-springboot\" target=\"_blank\" rel=\"noopener\">Github<\/a>.<\/p>\n<p>For in-depth knowledge on executing logic on Startup, you can check my Udemy Best Seller Course <a href=\"https:\/\/www.udemy.com\/course\/spring-framework-5-beginner-to-guru\/\" target=\"_blank\" rel=\"noopener\">Spring Framework 5: Beginner to Guru<\/a><br \/>\n<a href=\"https:\/\/www.udemy.com\/course\/spring-framework-5-beginner-to-guru\/\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7721\" src=\"http:\/\/springframework.guru\/wp-content\/uploads\/2021\/09\/spring5guru.jpg\" alt=\"\" width=\"800\" height=\"315\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>While developing a Spring Boot Application, sometimes we need to run a piece of code at startup. This code can be anything. You might want to log certain information or run some cron jobs or send some notifications. Or you might even want to start the application with seed data in the database. In this [&hellip;]<a href=\"https:\/\/springframework.guru\/bootstrapping-data-in-spring-boot\/\" class=\"df-link-excerpt\">Continue reading<\/a><\/p>\n","protected":false},"author":111,"featured_media":4655,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[21,104],"tags":[379,40,29],"class_list":["post-7636","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-spring","category-spring-boot","tag-bootstrap-data","tag-spring","tag-spring-boot"],"jetpack_publicize_connections":[],"aioseo_notices":[],"modified_by":"jt","jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/springframework.guru\/wp-content\/uploads\/2017\/07\/NewBannerBOOTSWeb.jpg","jetpack_shortlink":"https:\/\/wp.me\/p5BZrZ-1Za","_links":{"self":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts\/7636"}],"collection":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/users\/111"}],"replies":[{"embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/comments?post=7636"}],"version-history":[{"count":35,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts\/7636\/revisions"}],"predecessor-version":[{"id":7766,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts\/7636\/revisions\/7766"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/media\/4655"}],"wp:attachment":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/media?parent=7636"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/categories?post=7636"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/tags?post=7636"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}