0% found this document useful (0 votes)
443 views110 pages

Spring Boot: Claudia Zhou 2018.05.23

Spring Boot is a framework for building stand-alone, production-grade Spring based Applications that can be "just run". It takes an opinionated view of the Spring platform and third-party libraries so that new and existing Spring developers can quickly get started with minimal configuration. Spring Boot features include embedded Tomcat, Jetty, or Undertaken servers, automatic configuration, and starter dependencies to simplify build configurations.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
443 views110 pages

Spring Boot: Claudia Zhou 2018.05.23

Spring Boot is a framework for building stand-alone, production-grade Spring based Applications that can be "just run". It takes an opinionated view of the Spring platform and third-party libraries so that new and existing Spring developers can quickly get started with minimal configuration. Spring Boot features include embedded Tomcat, Jetty, or Undertaken servers, automatic configuration, and starter dependencies to simplify build configurations.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 110

Spring Boot

Claudia Zhou
2018.05.23
Spring
2002
2004
2005
Spring Modules
• Inversion of Control container
• Aspect-oriented programming
• Data access
• Transaction management
• Model-view-controller
• Remote Access framework
• Convention-over-configuration
• Batch processing
• Authentication and authorization
• Remote Management
• Messaging
• Testing
Inversion of Control
vs
Dependency Injection
IoC
Inversion of Control
IoC
Inversion of Control Flow
Martin Fowler
https://martinfowler.com/bliki/In
versionOfControl.html

https://www.martinfowler.com/a
rticles/injection.html
Command Line
#ruby
puts 'What is your name?'
name = gets
process_name(name)
puts 'What is your quest?'
quest = gets
process_quest(quest)
GUI
require 'tk'
root = TkRoot.new()
name_label = TkLabel.new() {text "What is Your Name?"}
name_label.pack
name = TkEntry.new(root).pack
name.bind("FocusOut") {process_name(name)}
quest_label = TkLabel.new() {text "What is Your Quest?"}
quest_label.pack
quest = TkEntry.new(root).pack
quest.bind("FocusOut") {process_quest(quest)}
Tk.mainloop()
Hollywood Principle
Don’t call us, we’ll call you.
Ex. HttpSessionListener
•sessionCreated()
•sessionDestroyed()
Ex. Template Method Pattern
Dependency Injection

One Form of IoC


Spring Stereotype
•@Component
•@Repository
•@Service
•@Controller
Spring @Autowired
Productivity of
Java Programmers
•50% Spring
•50% IDE
Boot
Boot Methods
1. Web https://start.spring.io/
2. IDE
3. CLI (command line)
claudia.zhou@claudiazhou:~/projects$ brew tap pivotal/tap
==> Tapping pivotal/tap
Cloning into '/usr/local/Homebrew/Library/Taps/pivotal/homebrew-tap'...
remote: Counting objects: 15, done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 15 (delta 0), reused 5 (delta 0), pack-reused 0
Unpacking objects: 100% (15/15), done.
Tapped 10 formulae (50 files, 36.6KB)

claudia.zhou@claudiazhou:~/projects$ brew install springboot


Updating Homebrew...
==> Installing springboot from pivotal/tap
==> Downloading https://repo.spring.io/release/org/springframework/boot/spring-
######################################################################## 100.0%
==> Caveats
Bash completion has been installed to:
/usr/local/etc/bash_completion.d

zsh completions have been installed to:


/usr/local/share/zsh/site-functions
==> Summary
🍺 /usr/local/Cellar/springboot/2.0.2.RELEASE: 7 files, 9.8MB, built in 5 seconds
claudia.zhou@claudiazhou:~/projects$ spring init --dependencies=web,data-jpa my-
project
Using service at https://start.spring.io
Project extracted to '/Users/claudia.zhou/projects/my-project'
First Project
package com.example.demo;

import org.springframework.boot.SpringApplication;
import
org.springframework.boot.autoconfigure.SpringBootApplicati
on;

@SpringBootApplication
public class DemoApplication {

public static void main(String[] args) {


SpringApplication.run(DemoApplication.class, args);
}
}

DemoApplication
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {

private static final Logger logger =


LoggerFactory.getLogger(DemoApplication.class);

public static void main(String[] args) {


SpringApplication.run(DemoApplication.class, args);
}

@Override
public void run(String... args) throws Exception {
logger.info("Hello World!");
}
}

CommandLineRunner
SQL Database
dependencies {
compile('org.springframework.boot:spring-boot-starter')
testCompile('org.springframework.boot:spring-boot-
starter-test')
}

build.gradle
dependencies {
compile('org.springframework.boot:spring-boot-starter-
jdbc')
runtime('mysql:mysql-connector-java')
testCompile('org.springframework.boot:spring-boot-
starter-test')
}

build.gradle
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=test
spring.datasource.password=test
spring.datasource.hikari.maximumPoolSize=1

application.properties
package com.example.demo.dao;

@Repository
public class DemoRepository {

private static final Logger logger =


LoggerFactory.getLogger(DemoRepository.class);

private final JdbcTemplate jdbcTemplate;

@Autowired
public DemoRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

public void demo() {


List<Map<String, Object>> list =
this.jdbcTemplate.queryForList("select
PARTITION_NAME, START, END from `partition`;");
logger.info("partitions: {}", list);
}
}

DemoRepository
@SpringBootApplication
public class DemoApplication implements CommandLineRunner
{

private final DemoRepository demoRepository;

@Autowired
public DemoApplication(DemoRepository demoRepository)
{
this.demoRepository = demoRepository;
}

@Override
public void run(String... args) throws Exception {
logger.info("Hello World!");
this.demoRepository.demo();
}
} DemoApplication
BeanPropertyRowMapper
package com.example.demo.domain;

public class Partition {

private String partitionName;

private Long start;

private Long end;

public String getPartitionName() {


return partitionName;
}

public void setPartitionName(String partitionName) {


this.partitionName = partitionName;
}

public Long getStart() {


return start;
}

public void setStart(Long start) {


this.start = start;
}

public Long getEnd() {


return end;
}

public void setEnd(Long end) {


this.end = end;
}
}

Partition
@Repository
public class DemoRepository {

private RowMapper<Partition> rowMapper = new


BeanPropertyRowMapper<>(Partition.class);

public void demo2() {


List<Partition> list =
this.jdbcTemplate.query("select
PARTITION_NAME, START, END from `partition`;", rowMapper);
logger.info("partitions: {}", list);
}
}

DemoRepository
public class Partition {

@Override
public String toString() {
return "Partition{" +
"partitionName='" + partitionName + '\'' +
", start=" + start +
", end=" + end +
'}';
}
}

Partition
package com.example.demo.domain;

public class Partition {

private String name;

private Long start;

private Long end;

// 省略 getter, setter, toString


}

Partition
@Repository
public class DemoRepository {

public void demo2() {


List<Partition> list =
this.jdbcTemplate.query("select
PARTITION_NAME as name, START, END from `partition`;",
rowMapper);
logger.info("partitions: {}", list);
}
}

DemoRepository
Lombok
dependencies {
compile('org.springframework.boot:spring-boot-starter-
jdbc')
compile('org.projectlombok:lombok')
runtime('mysql:mysql-connector-java')
testCompile('org.springframework.boot:spring-boot-
starter-test')
}

build.gradle
package com.example.demo.domain;

import lombok.Data;

@Data
public class Partition {

private String name;

private Long start;

private Long end;


}

Partition
YAML
spring:
datasource:
url: jdbc:mysql://localhost/test
username: test
password: test
hikari:
maximumPoolSize: 1

application.yaml
Spring Profiles
spring:
profiles:
active: ${NODE_ENV:dev}
datasource:
url: jdbc:mysql://localhost/test
username: test
password: test
hikari:
maximumPoolSize: 1

application.yaml
spring:
datasource:
hikari:
maximumPoolSize: 2

application-staging.yaml
RabbitMQ
dependencies {
compile('org.springframework.boot:spring-boot-starter-
amqp')
compile('com.fasterxml.jackson.core:jackson-databind')
}

build.gradle
package com.example.demo.component;

@Component
public class DemoRabbitSender {

private static final String queueName = "demo";

private final AmqpTemplate amqpTemplate;

@Autowired
public DemoRabbitSender(AmqpTemplate amqpTemplate) {
this.amqpTemplate = amqpTemplate;
}

public void send() {


Partition p = new Partition();
p.setName("demo");
p.setStart(11111L);
p.setEnd(99999L);

this.amqpTemplate.convertAndSend(queueName, p);
}
}

DemoRabbitSender
package com.example.demo.component;

@Component
public class DemoRabbitListener {

private static final Logger logger =


LoggerFactory.getLogger(DemoRabbitListener.class);

@RabbitListener(queues = "demo")
public void processMessage(Partition partition) {
logger.info("received: {}", partition);
}

DemoRabbitListener
package com.example.demo;

@Configuration
public class AppConfig {

/*
@Bean
public SimpleRabbitListenerContainerFactory
rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new
SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setMessageConverter(new Jackson2JsonMessageConverter());
return factory;
}
*/

@Bean
public MessageConverter messageConverter() {
return new Jackson2JsonMessageConverter();
}

AppConfig
@SpringBootApplication
public class DemoApplication implements CommandLineRunner
{

private final DemoRabbitSender demoRabbitSender;

@Autowired
public DemoApplication(DemoRepository demoRepository,
DemoRabbitSender demoRabbitSender) {
this.demoRepository = demoRepository;
this.demoRabbitSender = demoRabbitSender;
}

@Override
public void run(String... args) throws Exception {
demoRabbitSender.send();
}
}

DemoApplication
Scheduling
import
org.springframework.scheduling.annotation.EnableScheduling;

@Configuration
@EnableScheduling
public class AppConfig {
}

AppConfig
@SpringBootApplication
public class DemoApplication implements CommandLineRunner
{

@Override
public void run(String... args) throws Exception {
}

@Scheduled(fixedRate = 1000)
public void sendToRabbit() {
this.demoRabbitSender.send();
}
}

DemoApplication
Async
@Configuration
@EnableAsync
@EnableScheduling
public class AppConfig {

@Bean
public ThreadPoolTaskExecutor asyncExecutor() {
ThreadPoolTaskExecutor executor = new
ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setThreadNamePrefix("async-");
executor.setWaitForTasksToCompleteOnShutdown(true);

return executor;
}
}

AppConfig
@Component
public class DemoRabbitSender {

@Async
public void asyncSend() {
logger.info("asyncSendToRabbit()");
send();
}
}

DemoRabbitSender
@SpringBootApplication
public class DemoApplication implements CommandLineRunner
{

@Override
public void run(String... args) throws Exception {
this.demoRabbitSender.asyncSend();
this.demoRabbitSender.asyncSend();
this.demoRabbitSender.asyncSend();
}
}

DemoApplication
Redis
dependencies {
compile('org.springframework.boot:spring-boot-starter-
data-redis')
}

build.gradle
@Repository
public class DemoRedisRepository {

private static final Logger logger =


LoggerFactory.getLogger(DemoRedisRepository.class);

private StringRedisTemplate template;

@Autowired
public DemoRedisRepository(StringRedisTemplate template) {
this.template = template;
}

public void demo() {


Long size = this.template.opsForList().size("demoList");
logger.info("demoList size: {}", size);

String value = this.template.opsForList().index("demoList",


0);
logger.info("demoList[0]: {}", value);
}
}

DemoRedisRepository
@SpringBootApplication
public class DemoApplication implements CommandLineRunner
{

@Override
public void run(String... args) throws Exception {
this.demoRedisRepository.demo();
}
}

DemoApplication
MongoDB
dependencies {
compile('org.springframework.boot:spring-boot-starter-
data-mongodb')
}

build.gradle
spring:
data:
mongodb:
uri: mongodb://localhost/test

application.yaml
@Repository
public class DemoMongoRepository {

private static final Logger logger =


LoggerFactory.getLogger(DemoMongoRepository.class);

private static final String COLLECTION = "demo";

private final MongoTemplate mongoTemplate;

@Autowired
public DemoMongoRepository(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}

public void demo() {


List<HashMap> data = this.mongoTemplate.find(new Query(),
HashMap.class, COLLECTION);
logger.info("mongo data: {}", data);
}
}

DemoMongoRepository
Multiple Datasources
demo2:
datasource:
url: jdbc:mysql://localhost/test
username: test
password: test
hikari:
maximumPoolSize: 1

application.yaml
@Configuration
public class DbConfig {

@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}

@Bean(name = "demo2DataSource")
@ConfigurationProperties(prefix = "demo2.datasource")
public DataSource demo2DataSource() {
return DataSourceBuilder.create().build();
}
}

DbConfig
@Repository
public class Demo2Repository {

private JdbcTemplate jdbcTemplate;

private NamedParameterJdbcTemplate
namedParameterJdbcTemplate;

@Autowired
public void setDataSource(@Qualifier("demo2DataSource")
DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.namedParameterJdbcTemplate = new
NamedParameterJdbcTemplate(dataSource);
}
}

Demo2MongoRepository
ORM - Hibernate-JPA
• Generate entity from table
• Generate table from entity
• Auto-implemented CRUD
Unit Test
RESTful API &
Microservice
WebSocket
AWS
Actuator
Sample & References
• https://github.com/jiayun/spring-boot-
sample
• https://docs.spring.io/spring-
boot/docs/current/reference/
• https://docs.spring.io/spring/docs/current/s
pring-framework-reference/
Thanks

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy