> For the complete documentation index, see [llms.txt](https://amartyushov.gitbook.io/tech/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://amartyushov.gitbook.io/tech/frameworks/spring.md).

# Spring

## IoC, DI, DIP

<mark style="background-color:red;">**IoC**</mark> - In the context of service **containers**, **IoC** is achieved by allowing the framework to do the binding and **instantiation of dependencies**. Instead of the application having to create and use services, it is the framework that determines the moment when the instantiation is needed.

<mark style="background-color:red;">**Dependency injection**</mark> - Dependency Injection was the name coined by Martin Fowler in 2004 to have a better, and more <mark style="background-color:yellow;">**specific name**</mark> for this style, as opposed to the overly generic term **Inversion of Control** used by many frameworks.&#x20;

Dependency Injection is a software design technique in which the **creation** and **binding** of **dependencies** are done **outside of the dependent class**. Afterwards, said dependencies are provided already instantiated and ready to be used, hence the term “injection”; in contrast to the dependent class having to instantiate its dependencies internally, and having to know how to configure them, thus causing coupling.

<mark style="background-color:red;">**Dependency Inversion Principle (DIP)**</mark>

* High-level modules should not depend on low-level modules. Both should depend on abstractions.
* Abstractions should not depend on details. Details should depend on abstractions.

<figure><img src="/files/mepayyLfuCW1lDJTd30U" alt=""><figcaption></figcaption></figure>

the dependency direction is inverted, interfaces are determined at a higher level and classes in their same level depend on them, therefore they depend on abstractions. Additionally, lower-level class implementations depend on the interfaces defined at a higher level, therefore *details* now *depend on abstractions*.

If both client and service depend on an abstraction, then you essentially have an agreement that, if respected, will allow for the following:

* The client will be agnostic of who the dependency is, and instead rely on what it does
* The dependency will be guaranteed to behave in a way that is determined by the high-level policy
* The client can be reused in other contexts safely, trusting that its dependencies will respect the contract
* The dependency can always be replaced by another implementation that implements the same contract

## Good examples of full apps

[Microservice app with deployment and monitoring](https://github.com/sqshq/PiggyMetrics)

## Dependencies

* spring-boot-dev-tools
  * helps with hot reload of code changes (works faster then server restart)

## Properties

An order of property file loading

* bootstrap.properties
* application.properties

## Spring expression language

## Basic Auth

* `GET/... Request | Basic64 username:password` Header for every request
* Header `Authorization: Basic [hash]`
* Can not logout
* HTTPS recommended
* Simple and fast

```java
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/", "index", "/css/*", "/js/*")
                .permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .httpBasic();
    }
}
```

### CSRF (Cross site request forgery)

![](/files/-MGxLLSpPgTmzOqaGRTd)

* CSRF token have to be used for frond end backend communication
* for backend-backend not mandatory

Code pointers:

* CookieCsrfTokenRepository
* CsrfFilter

## OAuth2 authorization server

### @EnableAuthorizationServer

* enables Authorization Server
  * `o.s.s.o.provider.endpoint.AuthorizationEndpoint`
  * `o.s.s.o.provider.endpoint.TokenEndpoint`
  * see also `o.s.s.o.c.a.w.configuration.AuthorizationServerEndpointsConfiguration`&#x20;
* How to configure server? extend `o.s.s.o.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter`
* The user is responsible for securing "Authorization Endpoint" (**/oauth/authorize**) using normal Spring security features (i.e `@EnableWebSecurity`)
* But Token Endpoint (**/oauth/token**) is auto secured using HTTP Basic authentication on the client credentials
* Clients must be registered by providing a `o.s.s.o.provider.ClientDetailsService` through one or more AuthorizationServerConfigurers&#x20;
  * loadClientByClientId

### Authorization endpoint

* Implementation of the Authorization Endpoint from the OAuth2 specification
* Accepts authorization requests and handles user approval if the grant type is authorization code
* Should be secured. Only accessible to fully authenticated users
* POST `/oauth/authorize` param: user\_oauth\_approval

### TokenEndpoint

* Clients post requests with a grant\_type parameter (e.g. "authorization\_code") and others as determined by grant type
* Supported grant types are handled by `o.s.s.o.provider.TokenGranter`&#x20;
* Clients must be authenticated (`o.s.s.core.Authentication` ) to access this endpoint and the client id is extracted from the authentication token
  * best way: HTTP basic auth
* GET `/oauth/token`&#x20;
* POST `/oauth/token`&#x20;

## OAuth2 client

### @EnableOAuth2Client

#### Authorization Code Grant

* Enable configuration for an OAuth2 client in a web application that uses Spring Security and wants to use the *Authorization Code Grant* from one or more OAuth2 Authorization servers.
* you need a global servlet filter `org.springframework.web.filter.DelegatingFilterProxy` that delegates to a bean named `oauth2ClientContextFilter` .
* Once that filter is in place your client app can use another bean provided by annotation `o.s.s.o.client.token.AccessTokenRequest` to create a `o.s.s.o.client.OAuth2RestTemplate` .&#x20;

```java
@Bean
   public OAuth2RestOperations restTemplate(OAuth2ClientContext oauth2ClientContext) {
  		return new OAuth2RestTemplate(remote(), oauth2ClientContext);
  }
```

#### Client credentials grant

* do not need `AccessTokenRequest` or scoped `RestOperations`&#x20;
* they still need to use a filter to trigger `OAuth2RestOperations` to obtain a token when necessary

#### Password grant

* apps needs to set authentication  properties in the `OAuth2ProtectedResourceDetails` before using the `RestOperation`
* This means the resource details themselves also have to be per session

## Gateway

Spring Boot + WebFlux + Project Reactor

### Web Filters (Gateway filters)

![](/files/-MHVtCoQTXo6Y2ieXEcS)

The Handler Mapping manages the client's request. It checks whether it matches some configured route. Then, it sends the request to the Web Handler to execute the specific filter chain for this route. The dotted line splits the logic between pre- and post-filter logic. The income filters run before the proxy request. The output filters enter into action when they receive the proxy response. Filters provide mechanisms to modify the process in between.

[Good article](https://www.baeldung.com/spring-cloud-gateway-webfilter-factories)

## Security

### JWT

[Good video Security + JWT](https://www.youtube.com/watch?v=X80nJ5T7YpE)

## Spring Session

About HTTP session. Makes it easy to share sessions between services.

Storage for session:

* JDBC
* Gemfire (in-memory data grid)
* MongoDB
* Redis

## Microservice system participants

### [Config server](https://www.baeldung.com/spring-cloud-configuration)

***Spring Cloud Config*** is Spring's client/server approach for storing and serving distributed configurations across multiple applications and environments.

This configuration store is ideally versioned under *Git* version control and can be modified at application runtime. While it fits very well in Spring applications using all the supported configuration file formats together with constructs like *Environment*, [*PropertySource or @Value*](https://www.baeldung.com/properties-with-spring), it can be used in any environment running any programming language.

#### [Working example](https://github.com/amartyushov/Experiments/tree/master/java/spring/spring-cloud-config)

![](/files/-MJ7boesh3x6vYS1CEpl)

### Discovery service (Eureka) <a href="#id-8bab" id="id-8bab"></a>

[Intro link](https://medium.com/swlh/spring-cloud-service-discovery-with-eureka-16f32068e5c7)

Actually available discovery services in Spring cloud world:

* Eureka
* Zookeeper
* Cloud Foundry
* Consul

Service discovery is the process of one service dynamically discovering the network location (IP address and port) of another service to communicate with it.\
Service discovery mechanism uses a central registry to maintain the network locations of all the microservices. If for some reason the IP address and the port number of a particular microservice changes, new values will be immediately re-registered in the registry.\
&#x20;<img src="/files/-MIww-_LoHPUcbureVHm" alt="" data-size="original">&#x20;

![](/files/-MIx6bKYvgRNs2tZugTl)

1. Service A and service B registers in Eureka server, providing their application names and network locations.
2. Service A intends to access Service B. Therefore, it possesses the application name (not the network location) of service B.
3. Service A presents the application name of Service B to Eureka server and obtains the corresponding network location.
4. Service A uses the obtained network location of service B to make a request (via http or some other protocol).

#### Eureka Client Server Communication

* **Register:** Eureka client registers the information about the running instance to the Eureka server.
* **Renew:** Eureka client needs to renew the lease by sending heartbeats every 30 seconds. The renewal informs the Eureka server that the instance is still alive.\
  **Special Note:** Eureka server doesn’t poll service instances (client) to find out their availability. Instead, clients send a heartbeat to Eureka server to inform their availability.
* **Fetch Registry:** Eureka clients fetches the registry information from the server and caches it locally. After that, the clients use that information to find other services.
* **Cancel:** Eureka client sends a cancel request to Eureka server on shutdown. This removes the instance from the server’s instance registry thereby effectively taking the instance out of traffic.

#### [High availability](https://medium.com/swlh/spring-cloud-high-availability-for-eureka-b5b7abcefb32)

* **Server Cluster:** Eureka can be deployed as a cluster of servers. In case, one of these Eureka servers crash, clients can still connect to the remaining Eureka servers and discover other services.
* **Client Side Caching:** Clients retrieve and cache registry information from Eureka server. In case all Eureka servers crash, clients still posses the last healthy snapshot of the registry. This is the default behaviour of Eureka clients and you don’t have to make any additional configurations to enable client side caching.

#### Server cluster

![](/files/-MIy6pfaGiA6p2guWj6s)

Eureka clients are aware of all the available server peers and in case one server crashes, they connect to the remaining servers and fetch registry information.

![](/files/-MIy7-EiKz5JiQZfDH8p)

An example can be found [here](https://github.com/amartyushov/Experiments/tree/master/java/spring/eureka-high-availability) based on [the article](https://medium.com/swlh/spring-cloud-high-availability-for-eureka-b5b7abcefb32).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://amartyushov.gitbook.io/tech/frameworks/spring.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
