> For the complete documentation index, see [llms.txt](https://ysfang82.gitbook.io/development-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ysfang82.gitbook.io/development-notes/programming-langauges/java/spring-boot.md).

# Spring Boot

**Key Concepts**

* [@EnableAutoConfiguration](https://blog.csdn.net/zxc123e/article/details/80222967)
  * Configure beans according to the jars under classpath
* Spring Bean Life Cycle

![spring bean life cycle - start up](/files/-MPllFlImxi4wU73zSmC)

* This 3 step happens in the Bean Creation Life-Cycle Callback:
  * When an object constructor is done, `@PostConstruct` will be called.&#x20;
  * If `InitializingBean` is implemented, then `afterPropertiesSet()` will be called. `InitializingBean`  is for Spring Boot to assign attributes with `@Autowired`.
  * If bean definition contains `init-method` or `@Bean(initmethod="..")` then it calls the init method.

![spring bean life cycle - shut down](/files/-MPlm-TAmobXOJzk3Bxf)

* Running logic on startup
  * implements `ApplicationListener` run logic after the Spring context has been initialized
  * implements `CommandLineRunner` receives arguments with String
  * implements `ApplicationRunner` receives arguments with `ApplicationArguments`

**Spring Cloud**

* Quickly enable and configure the common patterns between Spring Boot applications and build large distributed systems.

  * Eureka - Service Discovery
    * Analogy: ECS / API Gateway + Lambda
  * Feign - Declarative HTTP Client
    * Analogy: Route53 / ELB
  * Ribbon - Load balancing
    * Analogy: ELB
  * Hystrix - Circuit Breaker
    * Analogy: AWS App Mesh
  * Zuul - Intelligent Routing
    * Analogy: AWS API Gateway

**Automatic Test Implementation**

* Unit Tests
  * Declare test target and dependent members (with Mock / Spy)
  * Declare setUp with `@Before` to:
    * Initializing mocking with `MockitoAnnotations.initMocks(this);`
      * Or adding `@RunWith(MockitoJUnitRunner.class)` on class level
    * Assigning test target with constructor approach
      * Or adding `@InjectMocks` to test target
  * Within tests
    * Setting up given, when then for the mocks
    * Asserting value of results
    * Verifying execution times
    * Asserting arguments in methods invoked with `ArgumentCaptor`
* Integration Tests
  * Annotations on class level
    * `RunWith(SpringRunner.class)` for JUnit to invoke the runner
    * Load related components with:
      * `@SpringBootTest` for looking for a main configuration class (one with `@SpringBootApplication` for instance), and using it to start a Spring application context.
      * `@DataJpaTest` for testing JPA repository layer
      * `@WebMvcTest(XXController.class)` for testing controller layer
  * Declare test target with `@Autowired`
  * Declare dependent members with `@MockBean` to add mocking to Spring application context (optional)
  * PS. Spring Boot would initialize embedded DB with below files:
    * schema.sql
    * data.sql

**Interesting topics**

* Why `@Autowired` `HttpServletRequest` is thread safe
  * `@Autowired private HttpServletRequest request`;
  * `request` = `WebApplicationContextUtils.RequestObjectFactory`
  * `WebApplicationContextUtils.RequestObjectFactory.getObject()` = `WebApplicationContextUtils.currentRequestAttributes().getRequest()`
  * `WebApplicationContextUtils.currentRequestAttributes()` = `RequestContextHolder.currentRequestAttributes()`
  * `RequestContextHolder.currentRequestAttributes()` is stored in `ThreadLocal requestAttributesHolder`;
* `@Bean`
  * lite: with `@Component` or event without it. Beans would be created by every invocation.
  * standard: with `@Configuration`. the bean (proxy created with CGLIB) is created when invoked at first time and subsequent invocations would return the same bean.

**Reference**

* [Create your own Spring Boot Starter](https://iter01.com/553543.html)
