Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Spring Boot

442 views

Published on

Introduction to Spring Boot

Published in: Software
  • Be the first to comment

Spring Boot

  1. 1. Spring Boot Claudia Zhou 2018.05.23
  2. 2. Spring
  3. 3. 2002
  4. 4. 2004
  5. 5. 2005
  6. 6. 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
  7. 7. Inversion of Control vs Dependency Injection
  8. 8. IoC Inversion of Control
  9. 9. IoC Inversion of Control Flow
  10. 10. Martin Fowler
  11. 11. https://martinfowler.com/bliki/In versionOfControl.html https://www.martinfowler.com/a rticles/injection.html
  12. 12. Command Line #ruby puts 'What is your name?' name = gets process_name(name) puts 'What is your quest?' quest = gets process_quest(quest)
  13. 13. 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()
  14. 14. Hollywood Principle Don’t call us, we’ll call you.
  15. 15. Ex. HttpSessionListener •sessionCreated() •sessionDestroyed()
  16. 16. Ex. Template Method Pattern
  17. 17. Dependency Injection One Form of IoC
  18. 18. Spring Stereotype •@Component •@Repository •@Service •@Controller
  19. 19. Spring @Autowired
  20. 20. Productivity of Java Programmers •50% Spring •50% IDE
  21. 21. Boot
  22. 22. Boot Methods 1. Web https://start.spring.io/ 2. IDE 3. CLI (command line)
  23. 23. 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
  24. 24. 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'
  25. 25. First Project
  26. 26. DemoApplication 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); } }
  27. 27. CommandLineRunner @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!"); } }
  28. 28. SQL Database
  29. 29. build.gradle dependencies { compile('org.springframework.boot:spring-boot-starter') testCompile('org.springframework.boot:spring-boot- starter-test') }
  30. 30. build.gradle dependencies { compile('org.springframework.boot:spring-boot-starter- jdbc') runtime('mysql:mysql-connector-java') testCompile('org.springframework.boot:spring-boot- starter-test') }
  31. 31. application.properties spring.datasource.url=jdbc:mysql://localhost/test spring.datasource.username=test spring.datasource.password=test spring.datasource.hikari.maximumPoolSize=1
  32. 32. DemoRepository 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); } }
  33. 33. DemoApplication @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(); } }
  34. 34. BeanPropertyRowMapper
  35. 35. Partition 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; } }
  36. 36. DemoRepository @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); } }
  37. 37. Partition public class Partition { @Override public String toString() { return "Partition{" + "partitionName='" + partitionName + ''' + ", start=" + start + ", end=" + end + '}'; } }
  38. 38. Partition package com.example.demo.domain; public class Partition { private String name; private Long start; private Long end; // 省略 getter, setter, toString }
  39. 39. DemoRepository @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); } }
  40. 40. Lombok
  41. 41. build.gradle 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') }
  42. 42. Partition package com.example.demo.domain; import lombok.Data; @Data public class Partition { private String name; private Long start; private Long end; }
  43. 43. YAML
  44. 44. application.yaml spring: datasource: url: jdbc:mysql://localhost/test username: test password: test hikari: maximumPoolSize: 1
  45. 45. Spring Profiles
  46. 46. application.yaml spring: profiles: active: ${NODE_ENV:dev} datasource: url: jdbc:mysql://localhost/test username: test password: test hikari: maximumPoolSize: 1
  47. 47. application-staging.yaml spring: datasource: hikari: maximumPoolSize: 2
  48. 48. RabbitMQ
  49. 49. build.gradle dependencies { compile('org.springframework.boot:spring-boot-starter- amqp') compile('com.fasterxml.jackson.core:jackson-databind') }
  50. 50. DemoRabbitSender 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); } }
  51. 51. DemoRabbitListener 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); } }
  52. 52. AppConfig 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(); } }
  53. 53. DemoApplication @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(); } }
  54. 54. Scheduling
  55. 55. AppConfig import org.springframework.scheduling.annotation.EnableScheduling; @Configuration @EnableScheduling public class AppConfig { }
  56. 56. DemoApplication @SpringBootApplication public class DemoApplication implements CommandLineRunner { @Override public void run(String... args) throws Exception { } @Scheduled(fixedRate = 1000) public void sendToRabbit() { this.demoRabbitSender.send(); } }
  57. 57. Async
  58. 58. AppConfig @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; } }
  59. 59. DemoRabbitSender @Component public class DemoRabbitSender { @Async public void asyncSend() { logger.info("asyncSendToRabbit()"); send(); } }
  60. 60. DemoApplication @SpringBootApplication public class DemoApplication implements CommandLineRunner { @Override public void run(String... args) throws Exception { this.demoRabbitSender.asyncSend(); this.demoRabbitSender.asyncSend(); this.demoRabbitSender.asyncSend(); } }
  61. 61. Redis
  62. 62. build.gradle dependencies { compile('org.springframework.boot:spring-boot-starter- data-redis') }
  63. 63. DemoRedisRepository @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); } }
  64. 64. DemoApplication @SpringBootApplication public class DemoApplication implements CommandLineRunner { @Override public void run(String... args) throws Exception { this.demoRedisRepository.demo(); } }
  65. 65. MongoDB
  66. 66. build.gradle dependencies { compile('org.springframework.boot:spring-boot-starter- data-mongodb') }
  67. 67. application.yaml spring: data: mongodb: uri: mongodb://localhost/test
  68. 68. DemoMongoRepository @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); } }
  69. 69. Multiple Datasources
  70. 70. application.yaml demo2: datasource: url: jdbc:mysql://localhost/test username: test password: test hikari: maximumPoolSize: 1
  71. 71. DbConfig @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(); } }
  72. 72. Demo2MongoRepository @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); } }
  73. 73. ORM - Hibernate-JPA • Generate entity from table • Generate table from entity • Auto-implemented CRUD
  74. 74. Unit Test
  75. 75. RESTful API & Microservice
  76. 76. WebSocket
  77. 77. AWS
  78. 78. Actuator
  79. 79. 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/
  80. 80. Thanks

×