Showing posts with label Spring boot. Show all posts
Showing posts with label Spring boot. Show all posts

Friday, November 15, 2019

Spring Reactive: Spring WebFlux Vs Spring MVC


Details here:
Both work together to expand the range of available options. The two are designed for continuity and consistency with each other, they are available side by side, and feedback from each side benefits both sides. The following diagram shows how the two relate, what they have in common, and what each supports uniquely:
spring mvc and webflux venn
We suggest that you consider the following specific points:
  • If you have a Spring MVC application that works fine, there is no need to change. Imperative programming is the easiest way to write, understand, and debug code. You have maximum choice of libraries, since, historically, most are blocking.
  • If you are already shopping for a non-blocking web stack, Spring WebFlux offers the same execution model benefits as others in this space and also provides a choice of servers (Netty, Tomcat, Jetty, Undertow, and Servlet 3.1+ containers), a choice of programming models (annotated controllers and functional web endpoints), and a choice of reactive libraries (Reactor, RxJava, or other).
  • If you are interested in a lightweight, functional web framework for use with Java 8 lambdas or Kotlin, you can use the Spring WebFlux functional web endpoints. That can also be a good choice for smaller applications or microservices with less complex requirements that can benefit from greater transparency and control.
  • In a microservice architecture, you can have a mix of applications with either Spring MVC or Spring WebFlux controllers or with Spring WebFlux functional endpoints. Having support for the same annotation-based programming model in both frameworks makes it easier to re-use knowledge while also selecting the right tool for the right job.
  • A simple way to evaluate an application is to check its dependencies. If you have blocking persistence APIs (JPA, JDBC) or networking APIs to use, Spring MVC is the best choice for common architectures at least. It is technically feasible with both Reactor and RxJava to perform blocking calls on a separate thread but you would not be making the most of a non-blocking web stack.
  • If you have a Spring MVC application with calls to remote services, try the reactive WebClient. You can return reactive types (Reactor, RxJava, or other) directly from Spring MVC controller methods. The greater the latency per call or the interdependency among calls, the more dramatic the benefits. Spring MVC controllers can call other reactive components too.
  • If you have a large team, keep in mind the steep learning curve in the shift to non-blocking, functional, and declarative programming. A practical way to start without a full switch is to use the reactive WebClient. Beyond that, start small and measure the benefits. We expect that, for a wide range of applications, the shift is unnecessary. If you are unsure what benefits to look for, start by learning about how non-blocking I/O works (for example, concurrency on single-threaded Node.js) and its effects.

Monday, November 4, 2019

Spring Boot: Property File Read Order

Externalization of Config file is really important in any application, however sometime it gets confusing where we should keep the property file.

By default we tend to keep the property file in "resources folder" by naming it as "application.properties(yaml/yml)" or "application-{profile}.properties(yaml/yml)".

If you have seen any existing project where they are not using default location to store the property file, however still properties are getting loaded and if you are wondering, from where the properties are read, than here are the various locations from where Spring boot by default reads the application.properties(yaml/yml) file.

Evaluation order

1st Location: Under the classpath directly: generally build tools attach the resources folder in the classpath and while running application we can add file location in the classpath using command line.

2nd Location : under the /config folder of the classpath, in other sense just see do you have any /config folder in the classpath of the project. application.properties((yaml/yml) file inside it will be loaded.

3rd Location: under the project root directory itself.

4th Location: under the /config folder of the root directory.

The order of read is exactly as par location, the last location property will override the previous location in case of conflict.


These are the default settings, you are not happy with defaults ?

Spring Boot has hook for you in that case:

1. Do you want to change the default naming of config file ( i.e. application.properties(yaml/yml)) ? You can change it to any name, just you have to set "spring.config.name" environment variable value with the name you want to give to property file.

2.  Do you want to change the default locations ? you can change it using environment variable "spring.config.location". The only thing you have to take care of, if you are providing multiple file locations, the properties in the last file in the list will override the preceding in case of conflict. One major point to note spring will not read any default locations config files in this case.

3. Do you want to read default location files as well as the custom location file ? in that case above will not work, you have to set "spring.config.additional-location" environment variable with all additional files to read. These files will have higher precedence, in case of conflict, property values from these files will override.

4. you don't want to set environment variable ? We have to use @PropertySource annotation for loading the file. The only thing is in case of conflict, properties defined in the order above will override it. It has the second lowest priority in case of conflict.

5. Let's suppose you don't have handle of the project, you have been provided with jar only, for that kind of application we can define property files in the same location where the jar is, Spring boot will load that config and add it to jar.

Evaluation order

Properties files that are placed outside of your packaged jar override the ones inside your jar. Profile-specific files always take precedence. Properties are considered in the following order:
  • Profile-specific application properties outside of your packaged jar
  • Profile-specific application properties packaged inside your jar
  • Application properties outside of your packaged jar
  • Application properties packaged inside your jar

Saturday, November 2, 2019

Spring Boot: CommandLineRunner and ApplicationRunner

Do you want to run some code before Spring boot application starts, however after ApplicationContext is loaded ?

If Answer is Yes, you have 2 interfaces at your service - CommandLineRunner and ApplicationRunner.

Both have single method called run(...), one accepts String[] as argument, the other accepts 'ApplicationArguments' which is nothing but a nice wrapper around supplied args.

you can read more about it here.

@Component
@Order(1)
public class SampleCmdRunner implements CommandLineRunner {
    @Override
    public void run(String[] args) {
        System.out.println("Executing the command line runner);
    }
}
@Component @Order(2) public class SampleAppRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) { System.out.println("Executing SampleAppRunner");
} }


In case of multiple CommandRunner and ApplicationRunner we can order them using @Order annotation.

Spring Boot: Lazy Initialization Of Beans

Many times we don't want to load all the beans at the application start up. We want beans to come into existence when an actual call is made to them.

It could be the case where many of the beans never used, but loaded in context at the startup.

Isn't it waste of app startup time and memory as well.

Spring boot provides very easy way to enable lazy initialization of beans.

1. Using Property file:

              spring.main.lazy-initialization=true

The above will ensure all the beans are initialized when only required.

Lazily loading all beans could be problematic as well
1. It can suppress exceptions,
2. Memory overflow
3. In case of HTTP calls high throughput time,
4. Can confuse load balancer etc.

2. Using @Lazy Annotation: To target a specific bean to lazily load.

Just Remember if you are using @Lazy at the component level and adding that component using @Autowired, you mandatorily add @Lazy at both the places (i.e. @Component & @Autowired) for it to work.

We can use @Lazy(false) as well along with property file to lazily load all beans except the bean annotated with @Lazy(false)


@Component
@Lazy
public class MyLazyBean {
      public MyLazyBean() {
       log.info("MyLazyBean initialized");
    }
}

Public class App {
    @Lazy
    @Autowired
    private MyLazyBean mlb;
}
@Lazy @Configuration
public class ConfigClass { @Bean private A getA(){ return new A(); }
 @Bean  
 private B getB(){
   return new B();
 }
}

Friday, November 1, 2019

Spring Boot: Disabling Specific Auto-configuration

Spring Boot Auto Configuration is non-invasive. It allows you to control, what needs to be loaded and what not.

There are two ways you can exclude specific config exclusion

1. By Annotation: 

We can exclude using @EnableAutoConfiguration(exclude -{*.class})

  class like: DataSourceAutoConfiguration.class

We can exclude using @SpringBootApplication(exclude={*.class})

  class like: DataSourceAutoConfiguration.class

2. By Property Value:

add fully qualified name of the class in 'spring.autoconfigure.exclude' property like:

spring.autoconfigure.exclude= org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration







Wednesday, October 30, 2019

Spring Boot: Importance of @AutoConfiguration


Everyone must have seen magic of spring boot, where it auto adds all the necessary dependencies based on presence of jar, property etc...

Behind the scene the magic is done by @AutoConfiguration annotation.

Instead of saying the magic is done by @Autoconfiguration, I would say actual work is done by @Conditional annotations.

@Conditional annotation allows us to configure beans based on anything like classType, jar, value of property param etc...

I would suggest you guys to read about @Conditional very well, the all magic is done by this annotation only. @AutoConfiguration is just a wrapper.



If you need to find out what auto-configuration is currently being applied, and why, start your application with the --debug switch. Doing so enables debug logs for a selection of core loggers and logs a conditions report to the console.

Spring Boot: Parent POM importance

Everyone must have written few Spring boot code and exposed some applications.

if you have noticed every Spring boot application has below as parent 

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.5.RELEASE</version>
</parent>

What does the above line signifies, if you remove this, the project might not build.

Actually this one parent does the following behind the scene
1. Add all necessary config, like java versions. basedir etc.
2. include all resource files to path
3. Add necessary maven plugins
4. Add all necessary spring resources with versions, every parent version has supported versions of all necessary versions of spring resources like activemq version, hibernate version, cassandra-driver version etc...


essense is instead of you managing versions for all dependencies, spring will take care of versions which are stable.

so it is of great use.