Friday, February 23, 2018

Spring Framework - Injecting Map for Session Facade


Introduction

Spring Framework - Injecting Map Examples provided a working example for Injecting Map in Spring Framework.  With an extensive background in J2EE applications, and recently working with spring framework my immediate reaction was to use the same concept for implementing Session Facade in a web application.

Discussed in this blog is a simple implementation of Session Facade using Spring Framework. 

Demonstration Interface, and Classes

An interface Greeter with a single method getGreeting() which would return greeting is defined.  EnglishGreeter implementing Greeter would return "Welcome", and SpanishGreeter implementing the same would return "Bienvenido".  

Session Facade in Non-J2EE Applications

Similar to J2EE Applications several classes implement a common interface defining the specific business implementation.  Acknowledging that there are several methods of facade implementation, a simple implementation using switch statement to get Greeter based on language is shown below:

public interface Greeter {
  public String getGreeting();
}

public class EnglishGreeter implements Greeter {

  @Override
  public String getGreeting() {
    return "Welcome";
  }
}

public class SpanishGreeter implements Greeter {

  @Override
  public String getGreeting() {
    return "Bienvenido";
  }
}

public Greeter getGreeter(Sting lang) {
  Greeter greeter;
  switch (lang) {
    case "English":
      greeter = new EnglishGreeter();
      break;
    case "Spanish":
      greeter = new SpanishGreeter();
      break;
    case default:
      break;
    }
    return greeter;
}


Session Facade in J2EE Applications

Session Facade is one of the most employed design patterns in J2EE applications.  In case of Enterprise Java Beans(EJB) the session facade is implemented using a common interface with several EJBs implementing the base interface and incorporating the business specific logic within the implementing EJBs.

Again acknowledging that several implementations of session facade are possible, a simple implementation using if statement is demonstrated below: 


@Local
public interface Greeter {
  public String getGreeting();

}

@Stateless(name = "englishGreeter", mappedName = "ejb/englishGreeter")
public class EnglishGreeter implements Greeter {

  @Override
  public String getGreeting() {
    return "Welcome";
  }
}

@Stateless(name = "englishGreeter", mappedName = "ejb/spanishGreeter")
public class SpanishGreeter implements Greeter {

  @Override
  public String getGreeting() {
    return "Bienvenido";
  }
}

A simple client consuming above EJBs would look something similar to the following code:

@Local
public class GreeterClient {

  @EJB(mappedName = "ejb/englishGreeter")
  private Greeter englishGreeter;

  @EJB(mappedName = "ejb/spanishGreeter")
  private Greeter spanishGreeter;

  private Map<String, Greeter> map;

  public GreeterClient() {
    map.put("english", englishGreeter);
    map.put("spanish", spanishGreeter);
  }

  public void getGreeting(String lang) {
    Greeter greeter = map.get(lang);
    return greeter.getGreeting();
  }
}

Spring Framework Session Facade Injecting Map


Using Spring framework the same classes with annotations are shown below:

@Component(value="english")
@Qualifier("greeters")
public class EnglishGreeter implements Greeter {

  @Override
  public String getGreeting() {
    return "Welcome";
  }
}

@Component(value="english")
@Qualifier("greeters")
public class SpanishGreeter implements Greeter {

  @Override
  public String getGreeting() {
    return "Bienvenido";
  }
}

@Component
public class GreeterMapper {
    private Map<String, Greeter> map;

    @Autowired
    @Qualifier("greeters")
    public void setMap (Map<String, Greeter> map) {
        this.map = map;
    }

    public Map<String, Greeter> getMap () {
        return map;
    }
}

Spring framework uses value of the component as key, and class name as the value using the GreeterMapper.  The @Qualifier attribute enables grouping of the classes based on the value of the @Qualifier attribute.  GreeterMapper can be obtained from the SpringContext as shown below: 


GreeterMapper bean = context.getBean(GreeterMapper.class);
  
where context is the SpringContext.  Contents of GreeterBean demonstrating the mapping are shown below:

{english=com.teletubbies.util.EnglishGreeter@123f1134, spanish=com.teletubbies.util.SpanishGreeter@7d68ef40}

Language specific greeter from the facade can be obtained from a simple lookup of the map using Map's get method:

Greeter greeter = bean.getMap().get(lang);

Summary

With the help of sample code demonstrated simple facade implementation in ejb applications, and non-ejb applications without spring framework.  Compared with non-spring framework implementations, the annotation @Qualifier within the spring framework simplifies session facade implementation by automating the mapping for session facade. 


No comments:

Post a Comment