Java Spring FrameWork
Course Link - Chad Darby
Spring Core
Inversion of Control (IoC)
- In general approach whenever a components needs to use another component, it creates an instance of the compoments or requests for the component from a service provider, this creates a "tight coupling" between the components i.e whenever one component changes the other would be affected by the change
- To solve this Inversion of control reverses the traditional approach, in this approach whenever a component requires an object, it is passed as a prop rather than instatiating the object in the class.
-
Different Types of IoC
-
Dependency Injection: receive the dependencies through constructor, settor or an interface
- service locator: receive the dependencies by making a request to a central repository.
-
Factory Pattern: Have a interface class deliver the required dependencies
-
Spring framework uses spring container, to handle the Ioc functionalities
Annotations
- In spring application, the Application context contains the bean factory, by default spring does not create any class objects but by using the @component annotation, we can notify the bean factory.
- If we have multiple class dependencies, the spring framework is notified to fetch required beans using the @AutoWired annotation.
- scopes for objects, singleton and prototype (creates multiple objects each type getBean() is called)
@Configuration
- Annotation used to define class, which would be used to create the bean factory
@Bean
- This tag is used to declare beans inside the config file, all beans would be declared and made available during the init process
@Value
- sets the value in a bean, when its created
Layers
Controller
- responsible for handling all the incoming connections, use @RestController annotation, swagger can be integrated into the controller layer
Service
- responsible for handling all the bussiness logic, use @Service annotation
Respository
- responsible for connecting to the database, use @Repository annotation
JPA
- Java Persistence API, its a form of contract used to connect and talk with different databases
- ORM (object relation mapper) is the tool which translates java objects into data base schemas and data rows
Spring AOP
This is usefull for performance metrics, input validation and security and providing rbac, rollback transactions on exceptions, custom exception handling, caching, auditing, API rate limiting
Use Case | Description | Example Annotation |
---|---|---|
Logging & Monitoring | Logs method execution time and method calls. | @Around |
Security & Authorization | Restricts access based on user roles. | @Before |
Transaction Management | Ensures rollback on failures. | @Transactional |
Exception Handling | Centralized error handling across services. | @AfterThrowing |
Caching | Stores frequently used data to improve performance. | @Cacheable |
Auditing | Tracks user activity for compliance. | @Before |
API Rate Limiting | Prevents abuse by limiting API calls. | @Before |
Feature Toggles | Enables/disables features dynamically. | @Before |
Aspect Oriented Programming Concepts in a Nutshell
- Join Point (When): Think of it as a scene in the movie of your program's execution. It's where the action happens!
- Advice (What): This is the action! It's what happens at a particular scene (Join Point). It's like a plot twist in your program's execution.
- Aspect (Where-Conceptual): It's the script of your movie. It defines what plot twists (Advice) happen and where (Pointcut).
- Pointcut (Where-Operational): It's the specific scenes (Join Points) where the plot twists (Advice) occur. It's like a bookmark in your script (Aspect).
- Target Object (Whom): This is the main character. It's the object that experiences the plot twists (Advice).
- Weaving (How): This is the director's job. It's how the script (Aspect) is turned into a movie. In Spring AOP, this happens at runtime.
- Proxy (The Double): This is the stunt double in your movie. In Spring AOP, it's the object that is created after applying advice to the target object. It's the one that takes the hits, performs the stunts, and makes the main character (Target Object) look good.
Reactive Programming
process - a singular unit with a set of resources attached to it and used at the runtime thread - a singular unit in a process, which would share the resources and perform its actions scheduler - a part of the OS, which determines the duration for which a thread can execute
different types of IO calls
sync + blocking - thread sends a request, sits idle until response is available async - a thread, creates a new thread and delegates its task to fetch the results non-blocking - a thread perfroms the fetch request from the source and gets a call back when the response is ready non-blocking + async - a thread, creates a new thread to deleagate, the new thread reaches out to source and gets notified when response is delivered
-
communication patterns
-
request --> response : classic type of communication, for each request a response is delivered
- request --> streaming response: A single request is made and stream of response are delivered (booked a cab (req), server sends stream responses , (driver details, time to arrival))
- streaming request --> response : A single request is initiated to the server, and multiple requests are made (Galaxy watch sending sensor data to the server)
- bi directional : multiple requests and multiple responses (singular connections, but stream of req's and responses)
At the heart and core, reactive programming depends on the observer pattern
- in this pattern, a set of chained reactive calls are made, when any change is observed (input height in number --> conversion in diff units)
- pub/sub communication model
( workflow --> whenever a subscriber wants to connect to a publisher a subscription is generated which implements all the methods )
- processors - the intermit units between the publishers and subscribers who can acts as the both
- Reactor is the implementation of the pub/sub commnication model
- Mono: in this model, the publisher always emits 0 or 1 item
- Flux: in this model, publisher can emit 0 .. N items at once
- backpressure --> occurs when producers sends more data than a consumer can handle
- Mono.just(
<T>
value) --> creates a publisher with a single value, subscribers can subscribe to fetch the values - Mono.fromSupplier(()-> ()) --> used to delay the emit, the value is computed and emitted only when subscription is made.
Hot/ Cold publisher
- in case of cold publisher , each subscriber would get its own flux stream , in case of netflix , its acts as a cold pub
- in case of hot publisher , each subscriber would get the parent flux stream , in case of football match streaming
scheduler
- In general scenarion the creation of the flux object and the subscription and data stream is handled by the main thread
- If we want to avoid this and let only the main thread handle the creation process, we can use schedulers
to get this functionalities, reactor provides schedulers, reactor.core.scheduler
-
different modes
-
boundedElastic --> useful for network bound calls
- parallel --> useful for computive intense
subscribe on
- this method is used to attach the reactor core schedule for upstream, example
1 2 3 4 5 |
|
- in this case, the main thread handles the creation of the flux (pub), and the other parts are handled by the thread pool (when ever a sub arrives, a new thread fetchs the information from the pub, not the main thread)
publish on
- this method is used to attach the reactor core scheduler for downstream, whenever a publisher starts emitting data and sees a publisher on will assign the task to thread pool
1 2 3 4 5 |
|
the handling with the schedulers is handled by the scheduler
BackPressure
-
Occurs when subscriber is taking slowly than at the rate pub is producing (sub taking 100 items but pub producing 10000 items)
-
to handle this by default reactor.core uses a queue to maintain the buffer stream and has a default max value of 256
-
If the sub is taking at a slow rate, pub would produce till the max and wait until
methods to handle the back pressure manually (in case of flux.create())
- Add an additonal buffer (this would store the items and pass on to subscriber) (onBackPressureBuffer)
- thrown an error, in this case, whenever upstream produces more than the buffer size (an error will be thrown)
- Drop strategy --> in this case, a operator drops the extra items from the upstream, lets say sub takes 2 items and pub produces 20 items, 18 items would be dropped