Создадим первое приложение на Spring boot, пусть оно будеть чуть сложнее, чем HelloWorld! Начнем рассмотрение с pom файла:
<?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>spring-boot-journal</groupId> <artifactId>spring-boot-journal</artifactId> <version>1.0</version> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.3.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>Далее создадим сущность:
package ru.domain; import javax.persistence.*; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @Entity public class Journal { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String title; private Date create; private String summary; @Transient private SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy"); public Journal(){ } public Journal(String title, String summary,String create) throws ParseException{ this.title = title; this.create = format.parse(create); this.summary = summary; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public Date getCreate() { return create; } public void setCreate(Date create) { this.create = create; } public String getSummary() { return summary; } public void setSummary(String summary) { this.summary = summary; } public String getCreatedAsShort(){ return format.format(create); } public String toString(){ return "JournalEntry(" + "Id: " + id + ",Title: " + title + ",Summary: " + summary + ",Created: " + getCreatedAsShort() + ")"; } }Здесь ничего необычного, т.к. используем JPA - значит нам нужный аннотации Entity, ID и GeneratedValue. Используем 2 коструктора, с параметрами для нашего удобства и без парамтеров - для JPA. Аннотация Transient, говорит о том, что это поле не будет мапиться на таблицу.
Далее создадим репозиторий, используя SpringData
package ru.repository; import org.springframework.data.jpa.repository.JpaRepository; import ru.domain.Journal; public interface JournalRepository extends JpaRepository<Journal, Long> { }
Теперь веб контроллер:
package ru.web; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import ru.domain.Journal; import ru.repository.JournalRepository; import javax.annotation.Resource; import java.util.List; @Controller public class JournalController { @Resource private JournalRepository repository; @RequestMapping("/journal") public @ResponseBody List<Journal>getJournals(){ return repository.findAll(); } @RequestMapping("/") public String index(Model model){ model.addAttribute("journal", repository.findAll()); return "index"; } }Ну и сама веб страничка:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org" > <head> <meta charset="UTF-8"/> <meta http-equiv="Content-Type" content="text/html"/> <title>Spring Boot Journal</title> <link rel="stylesheet" type="text/css" media="all" href="css/bootstrap.min.css"/> <link rel="stylesheet" type="text/css" media="all" href="css/bootstrap-glyphicons.css"/> <link rel="stylesheet" type="text/css" media="all" href="css/styles.css"/> </head> <body> <div class="container"> <h1>Spring Boot Journal</h1> <ul class="timeline"> <div th:each="entry,status : ${journal}" > <li th:attr="class=${status.odd}?'timeline-inverted':''" > <div class="tl-circ"></div> <div class="timeline-panel"> <div> <h4> <span th:text="${entry.title}">TITLE</span> </h4> <p><small class="text-muted"> <i class="glyphicon glyphicon-time"></i> <span th:text="${entry.createdAsShort}">CREATED</span> </small> </p> </div> <div class="tl-body"> <p> <span th:text="${entry.summary}">SUMMARY</span> </p> </div> </div> </li> </div> </ul> </div> </body> </html>Ну и сам запуск приложения:
package ru; import org.springframework.beans.factory.InitializingBean; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration; import org.springframework.context.annotation.Bean; import ru.domain.Journal; import ru.repository.JournalRepository; @SpringBootApplication( exclude={ActiveMQAutoConfiguration.class} ) public class Application { public static void main(String[] arg){ SpringApplication.run(Application.class, arg); } @Bean InitializingBean saveData(JournalRepository repository){ return () -> { repository.save(new Journal("Get to know Spring Boot","Today I will learn Spring Boot","01/01/2016")); repository.save(new Journal("Simple Spring Boot Project","I will do my first Spring Boot Project","01/02/2016")); repository.save(new Journal("Spring Boot Reading","Read more about Spring Boot","02/01/2016")); repository.save(new Journal("Spring Boot in the Cloud","Spring Boot using Cloud Foundry","03/01/2016")); }; } }Запустив приложение, увидим:
Отлично, все работает! Но за счет чего? Ведь нет ни web.xml, ни xml или java конфигов для сприга. Если открыть аннотацию SpringBootApplication, то мы увидим следующее:
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package org.springframework.boot.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurationExcludeFilter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.context.TypeExcludeFilter; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.core.annotation.AliasFor; @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan( excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class} ), @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class} )} ) public @interface SpringBootApplication { @AliasFor( annotation = EnableAutoConfiguration.class, attribute = "exclude" ) Class<?>[] exclude() default {}; @AliasFor( annotation = EnableAutoConfiguration.class, attribute = "excludeName" ) String[] excludeName() default {}; @AliasFor( annotation = ComponentScan.class, attribute = "basePackages" ) String[] scanBasePackages() default {}; @AliasFor( annotation = ComponentScan.class, attribute = "basePackageClasses" ) Class<?>[] scanBasePackageClasses() default {}; }И после этого становится все понятнее. Основная аннтоция - EnableAutoConfiguration. С ее помощью спринг использует автоконфигуратор, опираясь на classpath, аннотация, которые используются в коде. Например, спринг заметит, что у нас используется зависимость spring-boot-starter-web, и поймет, что у нас веб приложение и будет конфигурировать наше приложение, как веб. Так же к приложению будет вшит Tomcat для запуска и после сборки проекта, через mvn package мы сможем запустить наше приложение не используя дополнительный сервер приложений.
Комментариев нет :
Отправить комментарий