Monday, January 20, 2020

Microservices : Complete End to End Example

Reference 1: https://medium.com/@tharanganilupul/microservices-implementation-netflix-stack-ba4f4a57a79f

Friday, January 3, 2020

Spring Annotation Reference

Spring Annotations Reference

ANNOTATIONSDESCRIPTION
@Component, @Repository, and @Service@Component annotation is the generalized form considered as a candidate for auto-detection when using annotation-based configuration and classpath scanning. It extended to more specific forms such as @Controller, @Repository, and @Service.
@AutowiredThe XML files define string bean dependencies, and the same can be automatically detected by the Spring container by using the @Autowired annotation. This would eliminate the use of XML configurations.
@QualifierThere may be scenarios when you create more than one bean of the same type and want to wire only one of them with a property. Control this using @Qualifier annotation along with the @Autowired annotation.
@Required@Required annotation applies to bean property setter methods and enforces required properties
Difference between @Resource, @Autowired, and @InjectThis tutorial explains the difference between these three annotations @Resource, @Autowired and @Inject used for injecting the objects.
@Inject and @Named@Inject and @Named annotations are JSR-330 annotations were introduced in Spring 3 as an alternative for the spring annotations @Autowired and @Component.
@Resource, @PostConstruct, and @PreDestroyThis tutorial explains the JSR-250 annotations that Spring 2.5 introduces, which include @Resource@PostConstruct, and @PreDestroy annotations.
@RestController@RestController annotation is inherited from the @Controller annotation. This is the special version of @Controller annotation for implementing the RESTful Web Services. @RestController was added as part of the Spring 4 release.
@RequestHeader@RequestHeader annotation for facilitating us to get the header details easily in our controller class. This annotation would bind the header details with the method arguments, and it can be used inside the methods.
@ControllerAdvice@ControllerAdvice annotation used for defining the exception handler with specific exception details for each method. This component will handle any exception thrown on any part of the application.
@ModelAttribute@ModelAttribute annotation can be used as the method arguments or before the method declaration. The primary objective of this annotation to bind the request parameters or form fields to a model object.
@ConditionalThis tutorial explains one of the new features introduced in spring 4conditional annotation type.
@QueryThis spring data series tutorial explains @query annotation and how to create a custom query using the @query annotation.
@ProfileThis tutorial explains how to enable profiles in your spring application for different environments.
@ConfigurationInstead of using the XML files, we can use plain Java classes to annotate the configurations by using the @Configuration annotation. If you annotate a class with @Configuration, it indicates that the class defines the beans using the @Bean annotation.
@PathVariableWe have to use @PathVariable for accepting the customized or more dynamic parameters in the request paths.
@Controller, @RequestMapping, @RequestParam, @SessionAttributes, and @InitBinderThis tutorial explains some of the key annotations that are related to Spring MVC applications @Controller, @RequestMapping, @RequestParam, @SessionAttributes, and @InitBinder
Difference between @RequestParam and @PathVariableThis tutorial explains the difference between the two annotations @RequestParam and @PathVariable.
@RequestMappingYou can use @RequestMapping annotation for mapping web requests to particular handler classes or handler methods.
@Value This tutorial shows how to load the properties file values using the @Value annotation.
@Import@Import is the annotation used for consolidating all the configurations defined in various configuration files using @Configuration annotation.
@TransactionalUse annotation @Transactional to define a particular method that should be within a transaction.
@SpringBootApplicationThis is annotation is the heart of spring boot application. @SpringBootApplication indicates that it is the entry point for the spring boot application.
@EnableAutoConfigurationThis example demonstrates how to use the @EnableAutoConfiguration annotations for auto-configuring the spring boot applications.
@EnableCaching@EnableCaching annotation is the annotation-driven cache management feature in the spring framework. This annotation added to the spring in version 3.1.

Does notify/notifyall release the lock being held

I have to disagree with people who say notifyAll() releases the lock on the object over which waiting and notifying threads are being synchronized.
An example:
Consumer class contains a block:
synchronized(sharedObject){
if(sharedObject.isReadyToConsume() == false){
     sharedObject.wait();
}else {
    sharedObject.doTheThing();
    System.out.println("consumer consuming...");
 }
}
Scenario: Consumer class gets the lock on the sharedObject object, enters exclusively (it's inside the sync block) and sees that sharedObject has nothing ready yet (nothing to consume :) ) and it calls wait() method on the sharedObject. That way it releases the lock (stops the execution there!) and waits to be notified to continue when another Thread (Producer maybe) calls sharedObject.notify(); or sharedObject.notifyAll();. When it gets notified it continues from the wait() line
It's the sharedObject that keeps track of threads that asked it to be notified. When some Thread calls sharedObject.notifyAll() method the sharedObject will notify the waiting threads to wake up... Now, the tricky part is that a thread naturally releases the lock of the object when it reaches the end of its synchronized(sharedObject){} block. THe question is what happens if I call notifyAll() in that block??? notifyAll() wakes up the waiting threads, but the lock is still owned by the Thread that has just call notifyAll()
Look at the Producer snippet:
synchronized(sharedObject){
//We are exlusively working with sharedObject and noone can enter it
[... changing the object ...]
sharedObject.notifyAll();     //notifying the waiting threads to wake up

Thread.sleep(1000);           //Telling the current thread to go to sleep. It's holding the LOCK
System.out.println("awake...");
}
If notifyAll() would release the lock then the "awake..." would get printed out after the Consumer classes already start working with the sharedObject. This is not the case... The output shows that the Consumer is consuming the sharedObject after the Producer exits its sync block...
  • wait() - releases the lock and continues on the next line when it gets notified
  • notify(), notifyAll() - don't release the lock. They simply make waiting threads runnable again (not idle). They will have the right to enter when the current thread reaches the end of its sync block and the Thread scheduleder tells them that the lock has been released. The fight for the lock begins again

Thursday, January 2, 2020

Why does StringBuffer/StringBuilder not override equals or hashCode?

String str1 = new String("sunil");
String str2 = new String("sunil");

HashMap hm = new HashMap()
hm.put(str1,"hello");
hm.put(str2,"bye");
final hm:

hm = { sunil=bye }
In above code, str1 and str2 are two different String objects. Should they be added to the HashMap separately? The answer is NO. This is because before inserting/putting a value in HashMap, it internally checks and compares the hashCode values of str1, str2. Both return the same hashcode value because the String class overrides equals() and hashcode() methods. So upon executing hm.put(str2,"bye"); first key will get overriden with the new value. Now try this :

StringBuilder sb1 = new StringBuilder("sunil");
StringBuilder sb2 = new StringBuilder("sunil");

HashMap hm = new HashMap()
hm.put(sb1,"hello");//sb1 and sb2 will return different HashCode
hm.put(sb2,"bye");// StringBuffer/StringBuilder does not override hashCode/equals methods
final hm:

{sunil=hello, sunil=bye}
Both value will be added in hashMap because sb1 and sb2 both returns different hashcode. StringBuilder/ StringBuffer does not override equals() and hashCode() method.

Sun Microsystem wanted the programmer to allow adding 2 different String kind of Values in Hashtable or any other Hash Collections likes (HashSet,HashMap…),that’s the reason hashCode() and equals() were not overridden intentionally in StringBuffer,StringBuilder class.

Wednesday, January 1, 2020

How many objects will be created in this case string str="a"+"b"+"c" in Java?

No object is created at runtime.
The variable will be set to reference one object from the "constant pool".

Example

For this code:
public class MyClass {{
    String result = "a" + "b" + "c";
}}


Compiled using Oracle Java build 1.7.0_04-b20 you get this bytecode:

Constant pool:
   #1 = Class              #2             //  MyClass
   #2 = Utf8               MyClass
   #3 = Class              #4             //  java/lang/Object
   #4 = Utf8               java/lang/Object
   #5 = Utf8               <init>
   #6 = Utf8               ()V
   #7 = Utf8               Code
   #8 = Methodref          #3.#9          //  java/lang/Object."<init>":()V
   #9 = NameAndType        #5:#6          //  "<init>":()V
  #10 = String             #11            //  abc
  #11 = Utf8               abc
  #12 = Utf8               LineNumberTable
  #13 = Utf8               LocalVariableTable
  #14 = Utf8               this
  #15 = Utf8               LMyClass;
  #16 = Utf8               SourceFile
  #17 = Utf8               MyClass.java
{
  public MyClass();
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=2, args_size=1
         0: aload_0
         1: invokespecial #8                  // Method java/lang/Object."<init>":()V
         4: ldc           #10                 // String abc
         6: astore_1
         7: return
      LineNumberTable:
        line 2: 0
        line 3: 4
        line 2: 7
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       8     0  this   LMyClass;
}


However, concatenating three String variables like this:
public class MyClass {{
    String a = "a";
    String b = "b";
    String c = "c";
    String result = a + b + c;
}}



and the compiler will instead use a StringBuilder like this:
         0: aload_0
         1: invokespecial #8                  // Method java/lang/Object."<init>":()V
         4: ldc           #10                 // String a
         6: astore_1
         7: ldc           #12                 // String b
         9: astore_2
        10: ldc           #14                 // String c
        12: astore_3
        13: new           #16                 // class java/lang/StringBuilder
        16: dup
        17: aload_1
        18: invokestatic  #18                 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
        21: invokespecial #24                 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
        24: aload_2
        25: invokevirtual #27                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        28: aload_3
        29: invokevirtual #27                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        32: invokevirtual #31                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        35: astore        4
        37: return