Rediscovering Spring with Spring Boot - Meetupfiles.meetup.com/18258142/Rediscovering Spring with...

36
Rediscovering Spring with Spring Boot Gunith Devasurendra Asso. Tech Lead, CMS

Transcript of Rediscovering Spring with Spring Boot - Meetupfiles.meetup.com/18258142/Rediscovering Spring with...

Rediscovering Spring with Spring Boot

Gunith DevasurendraAsso. Tech Lead, CMS

Agenda

● Intro● Using Maven● Features and Conventions● Spring Data with Boot● Spring MVC with Boot● Spring Test with Boot● In Conclusion

Intro

Spring

● What?● Who?● Why?● Why not?● What is Boot?

Spring is a beast!

Spring.. Boot?

Spring made Simple

‘Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”’

New recommended way of running Spring programs

Goals

● Faster and more accessible initial setup● Default Configurations and the ability to Customize● No code generation and No XML configs

System Requirements

● Java 6+ (8 recommended)● Spring 4.1.5+

That's it! Simply include the appropriate spring-boot-*.jar files on your classpath.

---

● But, Recommended to use Build scripts: ○ Maven (3.2+), Gradle (1.12+)

● Also, Out-of-box supported Servlet containers: ○ Tomcat 7+, Jetty 8+, Undertow 1.1

Using Maven

Using Maven : Parent POM & Dependency

Inherit from the spring-boot-starter-parent project to obtain sensible defaults:

Java 6 compiler, UTF-8 code, Sensible resource filtering (ex: for application.properties), Sensible plugin configs

spring-boot-starter-parent extends from spring-boot-dependencies which holds a predefined set of dependencies.

● Could easily include dependencies from the parent ● Could override the versions by overriding MVN variables

<properties> <java.version>1.8</java.version></properties>

Using Maven : Starter POMs

Starter POMs are a set of convenient dependency descriptors that you can include in your application

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> ^-- No need for version as it comes</dependencies> from Parent POM

Has many more including: spring-boot-starter-amqp, spring-boot-starter-batch,spring-boot-starter-data-jpa, spring-boot-starter-data-rest,spring-boot-starter-mail, spring-boot-starter-mobile,spring-boot-starter-test, spring-boot-starter-logging,spring-boot-starter-ws spring-security-oauth2

Build File Generation

https://start.spring.io/

Features and Conventions

Main Class

@Configuration@EnableAutoConfiguration@ComponentScanpublic class Application {

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

}}

Just starts up deamon. To build CLI apps, use Spring Boot CLI

SpringApplication can be customized by calling different setters

Ex: Command line params, add listeners, shutdown hooks

@SpringBootApplication }

Code Structure

@ComponentScan automatically picks up all Spring components

com +- example +- myproject +- Application.java <- Main application class is in a | root package above other classes +- domain for correct @ComponentScan | +- Customer.java | +- CustomerRepository.java | +- service | +- CustomerService.java | +- web +- CustomerController.java

Defining Beans in @Configuration

Spring Boot favors Java-based @Configuration over XML Config, which is more traditional.

@Configurationpublic class AdsdaqCoreDatasourceConfiguration {

@Bean(name = “dataSourceMain”)@ConfigurationProperties(prefix = “datasource.main”)@Primarypublic DataSource dataSourceAdServer() { return DataSourceBuilder.create().build();}

}___

datasource.main.url=jdbc:mysql://localhost:3306/reviewdbdatasource.main.username=rootdatasource.main.password=admin

Enabling Auto Configuration

@EnableAutoConfiguration attempts to automatically configure the application based on the dependencies

At any point you can start to define your own @Configuration to replace specific parts of the auto-configuration.

Ex: if you add your own DataSource bean, the default embedded database support will back away.

There are factories defined in [MVN_repo]\org\springframework\boot\spring-boot-autoconfigure\[VER]\[JAR]\META-INF\spring.factories

These factories only loaded by if satisfied various conditions (ex: WebMvcAutoConfiguration)

Spring Beans

Spring provides the following stereotypes for a Spring Bean:

| Annotation | Meaning |+-------------+-----------------------------------------------------+| @Component | generic stereotype for any Spring-managed component || @Repository | stereotype for persistence layer || @Service | stereotype for service layer || @Controller | stereotype for presentation layer (spring-mvc) |

Any object with a stereotype as above is identified as a Spring Bean.

Spring will create them upon container startup and map them to any @Autowired annotation on an attribute/constructor

Setting Spring Config values to Beans

app.name=MyApp

listener.enable: true

connection.username: adminconnection.remote-address: 192.168.1.1

@Value("${app.name}")private String name;

@Component@ConditionalOnProperty(prefix = "listener", name = "enable", matchIfMissing = false)public class SomeListener { .. }

@Component@ConfigurationProperties(prefix="connection")public class ConnectionSettings {

private String username;@NotNullprivate InetAddress remoteAddress;// ... getters and setters

}

Spring Profiles

Support profiles where the application would act differently based on the active profile.

Ex: if ‘dev’ profile is passed via env. var.--spring.profiles.active=dev

If exists,

● Beans with @Profile("dev") will be activated● File application-dev.properties will be activated

Good for: Dev vs Prod settings, Local Dev vs Default settings

Logging

Spring uses Commons Logging as default.

By default logs to console unless logging.file or logging.path is set in application.properties.

Set log levels as follows:

logging.level.root=WARNlogging.level.org.springframework.web=DEBUG

If custom logging framework specific configs are to be used property logging.config

Log format also can be configured.

Building JAR and Running

Spring has plugins for Eclipse, IDEA etc.

Spring Boot has a Maven plugin that can package the project as an executable jar. Add the plugin to your <plugins> section if you want to use it:

<plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId>

</plugin>

Run java -jar target/myproject-0.0.1-SNAPSHOT.jar

Or mvn spring-boot:run

Spring Data with Boot

DB Access with Spring

If you use embeded DB, it only needs MVN dependency.

If you use a production database,

Spring will connection pooling using tomcat-jdbc by default (via Starters)

spring.datasource.url=jdbc:mysql://localhost/testspring.datasource.username=dbuserspring.datasource.password=dbpassspring.datasource.driver-class-name=com.mysql.jdbc.Driver

There are many more attributes

Data Access Using JPA and Spring Data - Entity

Using spring-boot-starter-data-jpa.

@Entity classes are ‘scanned’.

import javax.persistence.*;

@Entitypublic class City implements Serializable {

@Id@GeneratedValueprivate Long id;@Column(nullable = false)private String name;

}

More info about JPA at Hibernate Documentation

Data Access Using JPA and Spring Data - Repository

SQL are autogenerated.

public interface CityRepository extends PagingAndSortingRepository<City, Long> {

Page<City> findAll(Pageable pageable);

City findByNameAndCountryAllIgnoringCase(String name, String country);

@Query("select c from City c")Stream<City> findAllByCustomQueryAndStream();

}

● Repository’s subclass CrudRepository generates default CRUD methods in runtime.

● CrudRepository’s subclass PagingAndSortingRepository generates paging and sorting methods

Spring Data REST

Is able to easily open a REST interface to the DB using Spring Data REST by including a spring-boot-starter-data-rest dependency

Auto serialization

@RepositoryRestResource(collectionResourceRel = "cities", path = "cities")interface CityRepository extends Repository<City, Long> {

...}

Spring MVC with Boot

Spring MVC

Spring Boot comes with some auto configuration.

@Controller@RequestMapping(value="/users")public class MyRestController {

@RequestMapping(value="/{user}/cust", method=RequestMethod.GET)ModelAndView getUserCustomers(@PathVariable Long user) {

// ...}

}@RestController creates a REST service.

● Expects any static content to be in a directory called /static (or /public or /resources or /META-INF/resources) or at spring.resources.staticLocations

● /error mapping by default that handles all errors as a global error page.

@RequestMapping

@RequestMapping when added to a class would be prefixed to the @RequestMapping of the method

@RequestMapping method can be called with different parameters and different return types and it will work differently

Can also write @RequestMapping to be caught based on,

● RequestMethod (GET, POST..)● HTTP parameters (ex: params="myParam=myValue")● HTTP Headers (ex: headers="myHeader=myValue")

Spring MVC : Other features

● Templating: Auto-configuration support for: FreeMarker, Groovy, Thymeleaf, Velocity, Mustache○ Templates will be picked up automatically from

src/main/resources/templates

● Other REST Implementations: Support for JAX-RS and Jersey

● Embedded servlet container support: Comes with Starter Pom. Embeds Tomcat by default. Can go for Jetty, and Undertow servers as well○ Can set attributes server.port (default is 8080), server.

address, server.session.timeout values○ Can deploy as a WAR as well

Spring Test with Boot

Why need Spring for Tests?

Sometimes we need Spring context

Ex: DB related tests, Web related tests

Can set custom properties for tests using @TestPropertySource

Has Transaction support, esp for Integration testing for Auto-rollback

For TestNG, extend AbstractTransactionalTestNGSpringContextTests

In Conclusion

Thank you