Showing posts with label spring. Show all posts
Showing posts with label spring. Show all posts

Sunday, June 19, 2022

Spring Concepts

 Bean Scopes

  • Singleton
  • Prototype
  • Request
  • Session
  • Application
  • WebSocket
Reference : link

Injecting dependencies

  1. Constructor based
  2. Setter based
  3. Field based
    • This approach might look simpler and cleaner, but we don't recommend using it because it has a few drawbacks such as:
      • This method uses reflection to inject the dependencies, which is costlier than constructor-based or setter-based injection.
      • It's really easy to keep adding multiple dependencies using this approach. If we were using constructor injection, having multiple arguments would make us think that the class does more than one thing, which can violate the Single Responsibility Principle.
Reference : link

Injecting Prototype into Singleton

  • Every request to get prototype object from singleton bean will return same instance of prototype
  • In order to return different prototype bean there are different ways
    • Injecting ApplicationContext
    • Method Injection with @Lookup annotation
    • javax.inject API  
Reference  : link


Using bean outside of Spring context 

  • Implement ApplicationContextAware 
  • Inject into static field
  • Then call context.getBean method
public class ApplicationContextUtils implements ApplicationContextAware {
  private static ApplicationContext ctx;

 private static final String USER_SERVICE = "userServiceBean";

  @Override
  public void setApplicationContext(ApplicationContext appContext)
      throws BeansException {
    ctx = appContext;
  }

  public static ApplicationContext getApplicationContext() {
    return ctx;
  }

  public static UserService getUserService(){ 
return ctx.getBean(USER_SERVICE);
}
}

Reference : Stackoverflow
Reference  : link

BeanFactory vs ApplicationContext

  • BeanFactory loads beans on demand (Lazy loading)
  • ApplicationContext loads all beans at startup (Easger loading)
  • BeanFactory only when memory consumption is critical
  • ApplicationContext provides
    • Annotation based dependency injection
    • Event publication
    • Messaging (i18n)
    • Easy integration with Spring AOP feature
Reference : Baeldung


@ExceptionHandler and Global Handler

Reference : Baeldung


@Autowire

  • Allows Spring to resolve and inject collaborating beans into our bean
  • by declaring all the bean dependencies in a Spring configuration file, Spring container can autowire relationships between collaborating beans. This is called Spring bean autowiring
  • Resolving bean conflicts using @Qualifier annotation
  • @Qualifier helps to avoid ambiguity
  • @SpringBootApplication -  is equivalent to using @Configuration, @EnableAutoConfiguration, and @ComponentScan. When we run Spring Boot application, it will automatically scan the components in the current package and its sub-packages. Thus it will register them in Spring's Application Context, and allow us to inject beans using @Autowired.
  • We can use autowiring on properties, setters, and constructors
  • @Autowired(required = false) - makes bean optional. Otherwise throws NoSuchBeanDefinitionException 
Reference :  link

Design Patterns in Spring

  • Singleton - The singleton pattern is a mechanism that ensures only one instance of an object exists per application. This pattern can be useful when managing shared resources or providing cross-cutting services, such as logging. By default, Spring creates all beans as singletons.
  • Factory Method pattern - The factory method pattern entails a factory class with an abstract method for creating the desired object. For example : BeanFactory, ApplicationContextFactory are factory patterns
  • Proxy - Proxies are a handy tool in our digital world, and we use them very often outside of software (such as network proxies). In code, the proxy pattern is a technique that allows one object — the proxy — to control access to another object — the subject or service. For example : @Transactioin annotation is creating proxy object
  • Template - In many frameworks, a significant portion of the code is boilerplate code. For example, when executing a query on a database, the same series of steps must be completed:  Establish a connection, Execute query, Perform cleanup, Close the connection - These steps are an ideal scenario for the template method pattern.
    The template method pattern is a technique that defines the steps required for some action, implementing the boilerplate steps, and leaving the customizable steps as abstract. 
    For example : JDBC template, JMS, JPA templates 
Reference : link

Spring Events

  • The event class should extend ApplicationEvent if we're using versions before Spring Framework 4.2. As of the 4.2 version, the event classes no longer need to extend the ApplicationEvent class.
  • The publisher should inject an ApplicationEventPublisher object.
  • The listener should implement the ApplicationListener interface.
  • We can write our Custom events
  • Spring allows us to create and publish custom events that by default are synchronous. This has a few advantages, such as the listener being able to participate in the publisher’s transaction context.
  • In some cases, publishing events synchronously isn't really what we're looking for — we may need async handling of our events.We can turn that on in the configuration by creating an ApplicationEventMulticaster bean with an executor. The event, the publisher and the listener implementations remain the same as before, but now the listener will asynchronously deal with the event in a separate thread.
  • Existing framework events - ContextRefreshedEvent, ContextStartedEvent, RequestHandledEvent etc
Reference  - link

@Async

  • annotating a method of a bean with @Async will make it execute in a separate thread. In other words, the caller will not wait for the completion of the called method.
  • enabling asynchronous processing with Java configuration.by adding the @EnableAsync to a configuration class
  • Additional options : 
    • annotation – By default, @EnableAsync detects Spring's @Async annotation and the EJB 3.1 javax.ejb.Asynchronous. We can use this option to detect other, user-defined annotation types as well.
    • mode indicates the type of advice that should be used — JDK proxy based or AspectJ weaving.
    • proxyTargetClass indicates the type of proxy that should be used — CGLIB or JDK. This attribute has effect only if the mode is set to AdviceMode.PROXY.
    • order sets the order in which AsyncAnnotationBeanPostProcessor should be applied. By default, it runs last so that it can take into account all existing proxies.
  • @Async has two limitations
    • It must be applied to public methods only
    • Self-invocation — calling the async method from within the same class — won't work.
      The reasons are simple: The method needs to be public so that it can be proxied. And self-invocation doesn't work because it bypasses the proxy and calls the underlying method directly.
  • Methods With Void Return Type
  • Methods With Return Type - by wrapping the actual return in the Future
  • By default, Spring uses a SimpleAsyncTaskExecutor to actually run these methods asynchronously. But we can override the defaults at two levels: the application level or the individual method level.
    • Override the Executor at the Method Level
    • Override the Executor at the Application Level
  • Exception Handling -When a method return type is a Future, exception handling is easy. Future.get() method will throw the exception. But if the return type is void, exceptions will not be propagated to the calling thread. So, we need to add extra configurations to handle exceptions.
    • create a custom async exception handler by implementing AsyncUncaughtExceptionHandler interface
    • handleUncaughtException() method is invoked when there are any uncaught asynchronous exceptions
    • override the getAsyncUncaughtExceptionHandler() method to return our custom asynchronous exception handler
Reference : link

Monday, June 13, 2022

Spring Transaction Management

 

  • Transaction Propagation : Propagation defines our business logic's transaction boundary. Spring manages to start and pause a transaction according to our propagation setting. (in other words  : Defines how transactions relate to each other)
    • REQUIRED : Code will always run in a transaction. Creates a new transaction or reuses one if available.
    • REQUIRED_NEW : Code will always run in a new transaction. Suspends the current transaction if one exists.
    • SUPPORTS
    • MANDATORY
    • NEVER
    • NOT_SUPPORTED
    • NESTED

  • Transaction  Isolation :  solation is one of the common ACID properties: Atomicity, Consistency, Isolation, and Durability. Isolation describes how changes applied by concurrent transactions are visible to each other. (in other words :  Defines the data contract between transactions)
    Isolation Levels
    • DEFAULT 
    • READ_UNCOMMITTED : Allows dirty reads
    • READ_COMMITTED :  Does not allow dirty reads
    • REPEATABLE_READ : If a row is read twice in the same transaction, the result will always be the same 
    • SERIALIZABLE : Performs all transactions in a sequence
Each isolation level prevents zero or more concurrency side effects on a transaction:
  • Dirty read: read the uncommitted change of a concurrent transaction
  • Nonrepeatable read: get different value on re-read of a row if a concurrent transaction updates the same row and commits
  • Phantom read: get different rows after re-execution of a range query if another transaction adds or removes some rows in the range and commits

  • References

    Baeldung : link 

    Stackoverflow : link

    Transactions with Spring and JPA : link


    Saturday, March 12, 2022

    Spring Web MVC

    Front Controller

    the concept of the Front Controller in the typical Spring Model View Controller architecture

    At a very high level, here are the main responsibilities we're looking at:

    • Intercepts incoming requests
    • Converts the payload of the request to the internal structure of the data
    • Sends the data to Model for further processing
    • Gets processed data from the Model and advances that data to the View for rendering


    • DispatcherServlet plays the role of the Front Controller in the architecture.
    • The diagram is applicable both to typical MVC controllers as well as RESTful controllers
    • MVC applications are not service-oriented hence there is a View Resolver that renders final views based on data received from a Controller
    • RESTful applications are designed to be service-oriented and return raw data (JSON/XML typically). Since these applications do not do any view rendering, there are no View Resolvers – the Controller is generally expected to send data directly via the HTTP response

    MVC Controller : 

    @Controller
    @RequestMapping(value="Test")
    public class TestController{
    .....
    }

    Rest Controller :

    Maven Dependencies :  spring-web,  spring-webmvc,  jackson-databind

    @Controller
    public class TestController{
       @GetMapping(value = "/student/{studentId}")
        public @ResponseBody Student getTestData(@PathVariable Integer studentId) {
            Student student = new Student();
            student.setName("Peter");
            student.setId(studentId);

            return student;
        } 
    }
    @ResponseBody annotation on the method – which instructs Spring to bypass the view resolver and essentially write out the output directly to the body of the HTTP response.

    Spring Boot - @RestController

    @RestController
    public class RestAnnotatedController {
        @GetMapping(value = "/annotated/student/{studentId}")
        public Student getData(@PathVariable Integer studentId) {
            Student student = new Student();
            student.setName("Peter");
            student.setId(studentId);

            return student;
        }
    }
    @RestController annotation from Spring Boot is basically a quick shortcut that saves us from always having to define @ResponseBody. Help by pass view rendering stage and directly writing response to HTTP response body

    @RequestMapping
    the annotation is used to map web requests to Spring Controller methods

    Example 1 : Request Mapping with by path and HTTP method

    @RequestMapping(value = "/ex/foos", method = POST)
    @ResponseBody
    public String postFoos() {
        return "Post some Foos";
    }


    Example 2 : Request Mapping and HTTP header

    @RequestMapping(
      value = "/ex/foos", 
      headers = { "key1=val1", "key2=val2" }, method = GET)
    @ResponseBody
    public String getFoosWithHeaders() {
        return "Get some Foos with Header";
    }


    Example 3 : Mapping media types produced and consumed by controller

    @RequestMapping(value="/method6",
    produces={"application/json","application/xml"},
    consumes="text/html")
    @ResponseBody
    public String method6(){
    return "method6";
    }
    Above method can consume message only with Content-Type as text/html and is able to produce messages of type application/json and application/xml.


    Example 4 : Request Mapping with Path Variable

    @RequestMapping(value = "/ex/foos/{fooid}/bar/{barid}", method = GET)
    @ResponseBody
    public String getFoosBySimplePathWithPathVariables
      (@PathVariable long fooid, @PathVariable long barid) {
        return "Get a specific Bar with id=" + barid + 
          " from a Foo with id=" + fooid;
    }

    Example 5 : Request Mapping with Request Parameters

    @RequestMapping(value = "/ex/bars", method = GET)
    @ResponseBody
    public String getBarBySimplePathWithRequestParam( @RequestParam("id") long id) {
        return "Get a specific Bar with id=" + id;
    }

    http://localhost:8080/spring-rest/ex/bars?id=100

    Example 6 :  Request Mapping with Fallback

    @RequestMapping(
      value = "*", 
      method = { RequestMethod.GET, RequestMethod.POST ... })
    @ResponseBody
    public String allFallback() {
        return "Fallback for All Requests";
    }

    @RequestMapping New Shortcut Annotations

    • @GetMapping
    • @PostMapping
    • @PutMapping
    • @DeleteMapping
    • @PatchMapping



    Reference 1 :  Baeldung
    Reference 2 :  Journal Dev


    Sunday, June 18, 2017

    Spring Profiles

    * Spring provides @Profile annotation using which we create profiles. @Profile is used with @Configuration and spring stereotypes such as @Component, @Service etc.

    * Different profile is created for different environment. For example we can have environment such as production, development and testing. In development environment we can enable development profile and in production environment we can enable production profile and so on.

    *  A profile can be activated using (spring.profiles.active)
    • property file .properties/.yml
    • command line 
      • an Environment Variable (java -jar abc.jar  spring.profiles.active=prod)
      • a JVM Property (java -jar -Dspring.profiles.active=prod abc.jar)
      • You can set list of profiles like ; java -jar -Dspring.profiles.active="prod,test,x" abc.jar
    • programmatically
    • Context parameter in web.xml
    • @ActiveProfile in test
    * When we add active profile using command line then the active profile added in property file is replaced

    *We can add active and default profile programmatically by using ConfigurableEnvironment
     
     *You can also configure profile using spring.profiles.include that will be included for every active profile.

    *In spring boot testing we can add active profile by using @ActiveProfiles annotation

     *We can create property file using profile name using the convention application-{profile}.properties|yml

    * In application.yml file you can define  active profile using spring.profiles.active=dev 
    
    * We can add active profiles using command line with java command. In this case active profile configured in property file will be replaced by active profile passed in command line

    * How to set active profile programatically
      public static void main(String[] args) {
          SpringApplication application = new SpringApplication(MyApplication.class);
          ConfigurableEnvironment environment = new StandardEnvironment();
          environment.setActiveProfiles("dev","test");
          application.setEnvironment(environment);
          application.run(args);
      }    

    *How to set default profile programatically - 1
      public static void main(String[] args) {
         SpringApplication application = new SpringApplication(MyApplication.class);
         ConfigurableEnvironment environment = new StandardEnvironment();
         environment.setDefaultProfiles("dev","test");
         application.setEnvironment(environment);
         application.run(args);
      }      

     * How to set default profile programatically -2
    @Profile({"dev","default"}) 

    *You can have negative profile. For example when you are annotating class with @Profile annotation, you can negotiate it. Like @Profile("!dev"). It means
    • if dev profile is active this bean won't be created
    • if dev profile is not active then this bean will be created. And will belong to any other profile than dev.

    Reference/Useful links






    Thursday, June 15, 2017

    Inversion of Control And Dependency Injection

    This post is about what is IOC container? And what is DI?

    * Inversion of Control (IoC) means that objects do not create other objects on which they rely to do their work. Instead, they get the objects that they need from an outside source (for example, an xml configuration file).
    Giving control to the container to get an instance of the object is called Inversion of Control., means instead of you are creating an object using the new operator, let the container do that for you.
    The main tasks performed by IoC container are: to instantiate the application class. to configure the object. to assemble the dependencies between the objects.

    * DI means the IoC principle of getting dependent object is done without using concrete objects but abstractions (interfaces). This makes all components chain testable, cause higher level component doesn't depend on lower level component, only from the interface. Mocks implement these interfaces.


    There are several basic techniques to implement inversion of control. These are:
    • Using a factory pattern
    • Using a service locator pattern
    • Using a dependency injection of any given below type:

      1). A constructor injection
      2). A setter injection
      3). An interface injection
      * Spring supports only Constructor Injection and Setter/Getter Injection.
    Useful/Source links:
    Stack Overflow Discussion
    Martin Fowler Defintions
    Short Video Definition of IOC