275 - Enterprise app - Mid

Lec1: Architecture and Spring

Performance measurement and Scalability

* Round trip time
* First-response time
* Load (current stress, Measured by # of users, # of queries)
* Throughput (QPS Queries Per Second, TPS, Transactions Per Second )
* Capacity (Maximum throughput)
* Scalability (How adding hardware improves performance, Vertical scalability vs horizontal scalability)

Horizontal scaling means that you scale by adding more machines into your pool of resources whereas Vertical scaling means that you scale by adding more power (CPU, RAM) to an existing machine.

Round-trip Time : the round-trip delay time (RTD) or round-trip time (RTT) is the length of time it takes for a signal to be sent plus the length of time it takes for an acknowledgement of that signal to be received.

Monolithic, in this context, means composed all in one piece. Monolithic software is designed to be self-contained; components of the program are interconnected and interdependent rather than loosely coupled as is the case with modular software programs. In a tightly-coupled architecture, each component and its associated components must be present in order for code to be executed or compiled
pros : shared- memory access will be faster than inter-process communication
it's easier to hook up components to cross-cutting concern
cons : make it difficult to isolate services for purpose such as independent scaling and code maintainability.

Layered software architecture:
Pros :
Easy to understand and communicate, Minimize dependencies, Easy to substitute
Cons : Cascading changes, May harm performance

Three principal layers:
* Presentation : Display of information, user interaction
* Domain (AKA: Service, Business Logic) : Where the real computing is: validation, calculation, dispatching, etc
* Data source : Communication with database, messaging, and external services

✦ Spring

  • Open source application framework
  • Comprehensive and lightweight
  • Alternative to, replacement for, or addition to EJB

Why Spring?

  • No-intrusive framework
    • Minimal changes to run with or without Spring (POJOs allowed)
    • Minimal lock-in: easy migration
  • Promotes good programming practices
    • Program to interfaces, not implementations
    • Convention over configuration
  • Lightweight, flexible, and allows pick-and-choose
  • Does not reinvent the wheel

Inversion of Control:

In traditional programming, the custom code that expresses the purpose of the program calls into reusable libraries to take care of generic tasks, but with inversion of control, it is the framework that calls into the custom, or task-specific, code.

  • <bean name> : object name
  • <class> : bound to an object instance of type
  • <value> : parameter
  • <constructor-org> : constructor with arguments
    • <type> : Resolving constructor ambiguity (overloading)by type specification
    • <index> : Constructor argument index can be used to de-ambiguate as well

Names vs ID: Both need to be unique, but neither required. Names can be multiple

"non-intrusive" means that your application code doesn't need to depend on the Spring framework directly. Anything that can inject the appropriate dependencies will (theoretically) work just as well.

Convention over configuration (also known as coding by convention) is a software design paradigm used by software frameworks that attempts to decrease the number of decisions that a developer using the framework is required to make without necessarily losing flexibility.

Convention over configuration is a simple concept that is primarily used in programming. It means that the environment in which you work (systems, libraries, language…) assumes many logical situations by default, so if you adapt to them rather than creating your own rules each time, programming becomes an easier and more productive task.

The goal is to decrease the number of decisions the programmer has to make and eliminate the complexity of having to configure all and each of the areas of application development. The immediate result is that you can create many more things in less time.


Spring bean reference

1. Bean in different XML files

In Spring, beans can “access” to each other by specify the bean references in the same or different bean configuration file.

<ref bean="someBean"/>

In this example, the bean “OutputHelper” declared in ‘Spring-Common.xml‘ can access to other beans in ‘Spring-Output.xml‘ – “CsvOutputGenerator” or “JsonOutputGenerator“, by using a ‘ref’ attribute in property tag.

2. Bean in same XML file

If you are referring to a bean in same XML file, you can reference it with ‘ref‘ tag, ‘local‘ attribute.

<ref local="someBean"/>

In this example, the bean “OutputHelper” declared in ‘Spring-Common.xml‘ can access to each other “CsvOutputGenerator” or “JsonOutputGenerator“.

Spring FactoryBean Example

A factory bean is a bean that serves as a factory for creating other beans within the IoC container. Conceptually, a factory bean is very similar to a factory method, but it is a Spring-specific bean that can be identified by the Spring IoC container during bean construction and can be used by container to instantiate other beans.

Creating beans using FactoryBean

To create a factory bean, all you have to do is to implement the FactoryBean interface by your creator bean class which will be creating actual other beans. Or to keep it simple, you can extend AbstractFactoryBean class.

By extending the AbstractFactoryBean class, your factory bean can simply override the createInstance() method to create the target bean instance. In addition, you have to return the target bean’s type in the getObjectType() method for the auto-wiring feature to work properly.

public class EmployeeFactoryBean extends AbstractFactoryBean<Object>
{
    /This method will be called by container to create new instances
    @Override
    protected Object createInstance() throws Exception
    {
        //code
    }

    //This method is required for autowiring to work correctly
    @Override
    public Class<EmployeeDTO> getObjectType() {
        return EmployeeDTO.class;
    }
}

Dependency checking modes

4 dependency checking modes are supported:

  • none – No dependency checking.
  • simple – If any properties of primitive type (int, long, double…) and collection types (map, list..) have not been set, UnsatisfiedDependencyException will be thrown.
  • objects – If any properties of object type have not been set, UnsatisfiedDependencyException will be thrown.
  • all – If any properties of any type have not been set, an UnsatisfiedDependencyException will be thrown.

spring’s dependency checking in bean configuration file is used to make sure all properties of a certain types (primitive, collection or object) have been set. In most scenarios, you just need to make sure a particular property has been set, but not all properties..

For this case, you need @Required annotation, see following example :

public class Customer 
{
    private Person person;
    private int type;
    private String action;

    public Person getPerson() {
        return person;
    }
    @Required
    public void setPerson(Person person) {
        this.person = person;
    }
}

Simply apply the @Required annotation will not enforce the property checking, you also need to register an RequiredAnnotationBeanPostProcessor to aware of the @Required annotation in bean configuration file.

The RequiredAnnotationBeanPostProcessor can be enabled in two ways.

1. Include <context:annotation-config />

<context:annotation-config />

2. Include RequiredAnnotationBeanPostProcessor

<bean 
class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>

    <bean id="CustomerBean" class="com.mkyong.common.Customer">
        <property name="action" value="buy" />
        <property name="type" value="1" />
    </bean>

    <bean id="PersonBean" class="com.mkyong.common.Person">
        <property name="name" value="mkyong" />
        <property name="address" value="address ABC" />
        <property name="age" value="29" />
    </bean>

</beans>

If you run it , the following error message will be throw, because person property is unset.

org.springframework.beans.factory.BeanInitializationException: 
    Property 'person' is required for bean 'CustomerBean'

Spring Auto-Wiring Beans

In Spring framework, you can wire beans automatically with auto-wiring feature. To enable it, just define the “autowire” attribute in <bean>.

<bean id="customer" class="com.mkyong.common.Customer" autowire="byName" />

In Spring, 5 Auto-wiring modes are supported.

  • no – Default, no auto wiring, set it manually via “ref” attribute
  • byName – Auto wiring by property name. If the name of a bean is same as the name of other bean property, auto wire it.
  • byType – Auto wiring by property data type. If data type of a bean is compatible with the data type of other bean property, auto wire it. If more than one bean is found, an UnsatisfieDpendencyException will be thrown.
  • constructor – byType mode in constructor argument.
  • autodetect – If a default constructor is found, use “autowired by constructor”; Otherwise, use “autowire by type”.

In Spring, you can use @Autowired annotation to auto wire bean on the setter method, constructor or a field. Moreover, it can autowired property in a particular bean

Lec2 : Advanced Spring IoC Container, Google Guice, and Dagger

factory-method: factory-method is the method that will be invoked while injecting the bean. It is used when the factory method is static

factory-bean: factory-bean represents the reference of the bean by which factory method will be invoked. It is used if factory method is non-static.

  • Create beans by a static factory method

In Spring framework, if you want to create a bean by invoking a static factory-method, whose purpose is to encapsulate the object-creation process in a static method then you could use factory-method attribute.

  • Create beans by an instance factory method

BeanScope

Scope Description
singleton Scopes a single bean definition to a single object instance per Spring IoC container.
prototype Scopes a single bean definition to any number of object instances.
request Scopes a single bean definition to the lifecycle of a single HTTP request; that is each and every HTTP request will have its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware SpringApplicationContext.
session Scopes a single bean definition to the lifecycle of a HTTP Session. Only valid in the context of a web-aware SpringApplicationContext.
global session Scopes a single bean definition to the lifecycle of a global HTTP Session. Typically only valid when used in a portlet context. Only valid in the context of a web-aware Spring ApplicationContext.

Singleton:

Pros of singleton:
• Natural, conceptual simplicity
• Memory friendly

Cons of singleton
• May not simplify concurrency control
• Not allowing inheritance

The big difference between a singleton and a bunch of static methods is that singletons can implement interfaces, so you can pass around the singleton as if it were "just another" implementation.

Spring Bean Life Cycle

Singleton Scope vs Singleton Pattern

Singleton scope in Spring is not same as singleton pattern. Some of the main differences between these 2 are

  • Singleton pattern ensures one instance of a particular class of per class loader.
  • Spring Singleton is “per container per bean”.

Spring guarantees to create only one bean instance for given bean id definition per container.Singleton pattern ensures that one and only one instance is created per ClassLoader.

Spring Bean Initialize and Destroy

Spring bean factory is responsible for managing the life cycle of beans created through spring container. The life cycle of beans consist of call back methods which can be categorized broadly in two groups:

  • Post initialization call back methods
  • Pre destruction call back methods

Spring framework provides following 4 ways for controlling life cycle events of a bean:

InitializingBean and DisposableBean callback interfaces

public class ExampleBean implements InitializingBean {
   public void afterPropertiesSet() {
      // do some initialization work
   }
}
public class ExampleBean implements DisposableBean {
   public void destroy() {
      // do some destruction work
   }
}

● Custom init() and destroy() methods in bean configuration file

<bean id = "exampleBean" class = "examples.ExampleBean" init-method = "init" destroy-method = "destroy"/>

@PostConstruct and @PreDestroy annotations

@PostConstruct
public void initIt() throws Exception {
  System.out.println("Init method after properties are set : " + message);
}

@PreDestroy
public void cleanUp() throws Exception {
  System.out.println("Spring Container is destroy! Customer clean up");
}

● Reducing XML with annotation

Making Beans Aware of the Container

AWARE INTERFACE METHOD TO OVERRIDE PURPOSE
ApplicationContextAware void setApplicationContext(ApplicationContext applicationContext) throws BeansException; Interface to be implemented by any object that wishes to be notified of the ApplicationContext that it runs in.
BeanFactoryAware void setBeanFactory (BeanFactory beanFactory) throws BeansException; Callback that supplies the owning factory to a bean instance.
BeanNameAware void setBeanName(String name); Set the name of the bean in the bean factory that created this bean.
MessageSourceAware void setMessageSource(MessageSource messageSource); Set the MessageSource that this object runs in.

Google Guice

What we've done here is, create a dependency between the TextEditor and the SpellChecker. In an inversion of control scenario, we would instead do something like this −

public class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   public TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }
}

Here, the TextEditor should not worry about SpellChecker implementation. The SpellChecker will be implemented independently and will be provided to the TextEditor at the time of TextEditor instantiation.

Dependency Injection is controlled by the Guice Bindings. Guice uses bindings to map object types to their actual implementations. These bindings are defined a module. A module is a collection of bindings as shown below −

public class TextEditorModule extends AbstractModule {
   @Override 
   protected void configure() {
      /*
         * Bind SpellChecker binding to WinWordSpellChecker implementation 
         * whenever spellChecker dependency is used.
      */
      bind(SpellChecker.class).to(WinWordSpellChecker.class);
   }
}

The Module is the core building block for an Injector which is Guice's object-graph builder. First step is to create an injector and then we can use the injector to get the objects.

public static void main(String[] args) {
   /*
      * Guice.createInjector() takes Modules, and returns a new Injector
      * instance. This method is to be called once during application startup.
   */

   Injector injector = Guice.createInjector(new TextEditorModule());
   /*
      * Build object using injector
   */
   TextEditor textEditor = injector.getInstance(TextEditor.class);   
}

In above example, TextEditor class object graph is constructed by Guice and this graph contains TextEditor object and its dependency as WinWordSpellChecker object

Create a binding annotation

@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
@interface WinWord {}
  • @BindingAnnotation − Marks annotation as binding annotation.
  • @Target − Marks applicability of annotation.
  • @Retention − Marks availability of annotation as runtime.

Mapping using binding annotation

bind(SpellChecker.class).annotatedWith(WinWord.class).to(WinWordSpellCheckerImpl.class);

Inject using binding annotation

@Inject
public TextEditor(@WinWord SpellChecker spellChecker) {
   this.spellChecker = spellChecker;
}

Mapping using named annotation

bind(SpellChecker.class).annotatedWith(Names.named("OpenOffice")).to(OpenOfficeWordSpellCheckerImpl.class);

Inject using @Named annotation

@Inject
public TextEditor(@Named("OpenOffice") SpellChecker spellChecker) {
   this.spellChecker = spellChecker;
}

Instance Binding

Guice provides a way to create bindings with value objects or constants. Consider the case where we want to configure JDBC url.

Inject using @Named annotation

@Inject
public void connectDatabase(@Named("JBDC") String dbUrl) {
   //...
}

This can be achived using toInstance() method.

bind(String.class).annotatedWith(Names.named("JBDC")).toInstance("jdbc:mysql

@Provides Methods

Guice provides a way to create bindings with complex objects using @provides method.

@Provides
public SpellChecker provideSpellChecker() {
   String dbUrl = "jdbc:mysql://localhost:5326/emp";
   String user = "user";
   int timeout = 100;
   SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
   return SpellChecker;
}

● @Provides method must be defined within a module, and it must have the annotation
**● Returns the bound type - invoked whenever the injector needs an instance of that type
● Bad practice to allow any kind of exception to be thrown -- runtime or checked
Use the ThrowingProviders extension if actually needed

Constructor Bindings

Guice provides a way to create bindings with specific constructor of an object using toConstructor() method.

@Override
protected void configure() {
   try {
      bind(SpellChecker.class)
         .toConstructor(SpellCheckerImpl.class.getConstructor(String.class));
   } catch (NoSuchMethodException | SecurityException e) {
      System.out.println("Required constructor missing");
   } 
}

● Solve the confusion when there are multiple constructors
**● No need to use the @Inject annotation on the constructor
● Caveat: each toConstructor() binding is scoped independently
● Caveat: manually constructed instances do not participate in AOP

Just-In-Time Bindings

If a type is needed, but no explicit bindings are found, the injector will attempt to create a Just-In-Time binding

Scopes

Guice returns a new instance every time when it supplies a value as its default behavior. It is configurable via scopes. Following are the scopes that Guice supports −

  • @Singleton − Single instance for lifetime of the application. @Singleton object needs to be threadsafe.
  • @SessionScoped − Single instance for a particular session of the web application. @SessionScoped object needs to be threadsafe.
  • @RequestScoped − Single instance for a particular request of the web application. @RequestScoped object does not need to be threadsafe.

At Class level

@Singleton
class SpellCheckerImpl implements SpellChecker {
   public SpellCheckerImpl(){}

   @Override
   public void checkSpelling() { 
      System.out.println("Inside checkSpelling." );
   }
}

At Configuration level

bind(SpellChecker.class).to(SpellCheckerImpl.class).in(Singleton.class);

Eager Singleton, or Lazy Singleton?

Guice to Dagger

Guice Dagger

Runtime injection with reflection

● Slow initialization

● Late failure

● Slow injection

● Non-trivial memory impact.

Injection based on static analysis

● Fail as early as possible

o compile time, not runtime.

● No reflection at runtime

o Super fast!

● Little memory impact

● Detects cyclic dependencies

● Fits well with Android

● Mostly using @Inject **and @Provides
● No explicit binding command
● All @Provides methods belong to a module
● @Module marks a module class

Caveats of Dagger
● No cyclic dependencies (DAG)
● No shortcut to bind interfaces to impls
● No late, dynamic, or conditional binding
● No servlet support, yet (available in 3rd party libs)

Lec 3 : Aspect Oriented Programming (AOP)

Aspect-Oriented Programming entails breaking down program logic into distinct parts called so-called concerns. The functions that span multiple points of an application are called cross-cutting concerns and these cross-cutting concerns are conceptually separate from the application's business logic.

Functional concerns and cross-cutting concern

Crosscutting-concerns :

  • Can be scattered across a number of different functional concerns
  • Can be tangled with other concerns
  • Common, and orthogonal

Aspect: (Abstraction of a crosscutting concern) is a module which has a set of APIs providing cross-cutting requirements. For example, a logging module would be called AOP aspect for logging. An application can have any number of aspects depending on the requirement.

Join point: (a point in the flow of program execution) This represents a point in your application where you can plug-in the AOP aspect. You can also say, it is the actual place in the application where an action will be taken using Spring AOP framework.

Advice: (code to implement a concern) This is the actual action to be taken either before or after the method execution. This is an actual piece of code that is invoked during the program execution by Spring AOP framework.

Pointcut: (a set of joinpoints, usually expressed as an expression) This is a set of one or more join points where an advice should be executed. You can specify pointcuts using expressions or patterns as we will see in our AOP examples.

Advice type

Advice is an action taken by an aspect at a particular join point. Different types of advice include “around,” “before” and “after” advice. The main purpose of aspects is to support cross-cutting concerns, such as logging, profiling, caching, and transaction management.

  1. @Before – Run before the method execution
  2. @After – Run after the method returned a result (@After is called no matter it returns or not)
  3. @AfterReturning – Run after the method returned a result, intercept the returned result as well. AfterReturning(pointcut="execution(* *.*(..))", returning="retVal") public void logAroundGetEmployee(Object retVal) { ... log.info(" The result is : " + retVal); }
  4. @AfterThrowing – Run after the method throws an exception AfterThrowing(pointcut="execution(* *.*(..))", throwing="e") public void logAroundGetEmployee(Throwable e) { ... log.info(" Exception has been captured: " + e); }
  5. @Around – Run around the method execution, combine all three advices above.

The order of the advice without order annotation :
Around Prior to the execution of the method tweet
Before the execution of the method tweet
User alex tweeted message: first tweet
After the execution of the method tweet
Around Finished the execution of the method tweet with result null

@After and @AfterThrowing in AspectJ:
if there is an exception and you have both advises, both of them will be executed.

API Return
getArgs() Returns the arguments at this join point.
getKind() Returns a String representing the kind of join point.
getSinganature() Returns the signature at the join point.
getTarget() Returns the target object.
getThis() Returns the currently executing object.

Execution and Call :
While the former intercepts all callers (i.e. the sources of method calls), the latter intercepts the calls themselves no matter where they originate from.

Specifying aspect precedence

When there’s more than one aspect applied to the same join point, the precedence/order of the aspects will not be determined unless you have explicitly specified it using either @Order annotation or org.springframework.core.Ordered interface.

Use @Pointcut to annotate a method, then the method can be used for pointcut expressions

A pointcut expression can appear as a value of the @Pointcut annotation@Pointcut("within(@org.springframework.stereotype.Repository *)") public void repositoryClassMethods() {}

The method declaration is called the pointcut signature. It provides a name that can be used by advice annotations to refer to that pointcut.
@Around("repositoryClassMethods()") public Object measureMethodExecutionTime(ProceedingJoinPoint pjp) throws Throwable { ...}

AspectJ

  • An aspect-oriented programming (AOP) extension created for the Java programming language
  • Available in Eclipse Foundation open-source projects, both stand-alone and integrated into Eclipse

Aspect Weaving

  • Compile-time weaving. When you have the source code for an application, ajc will compile from source and produce woven class files as output. The invocation of the weaver is integral to the ajc compilation process
  • Post-compile weaving (also sometimes called binary weaving) is used to weave existing class files and JAR files. As with compile-time weaving, the aspects used for weaving may be in source or binary form, and may themselves be woven by aspects
  • Load-time weaving (LTW) is simply binary weaving deferred until the point that a class loader loads a class file and defines the class to the JVM. To support this, one or more "weaving class loaders" are required

Lec4 : MVC Framework

https://www.tutorialspoint.com/spring/spring_web_mvc_framework.htm

Architecture

The Spring Web MVC framework provides Model-View-Controller (MVC) architecture and ready components that can be used to develop flexible and loosely coupled web applications. The MVC pattern results in separating the different aspects of the application (input logic, business logic, and UI logic), while providing a loose coupling between these elements.

  • The Model (Data and interfaces to manipulate data) encapsulates the application data and in general they will consist of POJO. (Plain old Java object)
  • The View (Any output representation of data) is responsible for rendering the model data and in general it generates HTML output that the client's browser can interpret.
  • The Controller (Connects and controls view and model) is responsible for processing user requests and building an appropriate model and passes it to the view for rendering.

The Spring Web model-view-controller (MVC) framework is designed around a DispatcherServlet that handles all the HTTP requests and responses. The request processing workflow of the Spring Web MVC DispatcherServlet is illustrated in the following diagram −

Following is the sequence of events corresponding to an incoming HTTP request to DispatcherServlet −

  • After receiving an HTTP request, DispatcherServlet consults the HandlerMapping to call the appropriate Controller.
  • The Controller takes the request and calls the appropriate service methods based on used GET or POST method. The service method will set model data based on defined business logic and returns view name to the DispatcherServlet.
  • The DispatcherServlet will take help from ViewResolver to pickup the defined view for the request.
  • Once view is finalized, The DispatcherServlet passes the model data to the view which is finally rendered on the browser.

Put this “context:component” in bean configuration file, it means, enable auto scanning feature in Spring. The base-package is indicate where are your components stored, Spring will scan this folder and find out the bean (annotated with @Component) and register it in Spring container.

MVC Controller

  • @Controller defines the class as a Spring MVC controller
  • Return value decides the view jsp
  • Values are passed through model object

@RequestMapping annotation as a method name resolver, which used to map URL to a particular method.

1) @RequestMapping annotations at only method level

In this type of usage of @RequestMapping annotations, you must give complete paths as value attribute.

@Controller
public class CustomerController{
    @RequestMapping("/customer/add.htm")
    public ModelAndView add(HttpServletRequest request,
        HttpServletResponse response) throws Exception {
        return new ModelAndView("CustomerAddView");
    }
     @RequestMapping(value={"/customer/remove","/customer/delete"})
    public ModelAndView remove(HttpServletRequest request,
        HttpServletResponse response) throws Exception {
        return new ModelAndView("employeesList");
    } 
}

2) @RequestMapping annotations at class level as well as method levels

@Controller
@RequestMapping("/employee-management/employees/*")
public class EmployeeController{
    @RequestMapping
    public String getAllEmployees(Model model){
        return "employeesList";
    }

    @RequestMapping("/add")
    public String addEmployee(EmployeeVO employee{
        return "employeesDetail";
    }
}

3) @RequestMapping annotations using only HTTP request types

@Controller
@RequestMapping("/employee-management/employees")
public class EmployeeController
{
    @RequestMapping (method =  RequestMethod.GET)
    public String getAllEmployees(Model model)
    {
        //application code
        return "employeesList";
    }

    @RequestMapping (method =  RequestMethod.POST)
    public String addEmployee(EmployeeVO employee)
    {
        //application code
        return "employeesDetail";
    }
}

Handler interceptors

We’ll use the HandlerInterceptor to perform actions before handling, after handling or after completion (when the view is rendered) of a request.

The interceptor can be used for cross-cutting concerns and to avoid repetitive handler code like: logging, changing globally used parameters in Spring model etc.

  • preHandle – called before the actual handler is executed, but the view is not generated yet
  • postHandle – called after the handler is executed
  • afterCompletion called after the complete request has finished and view was generated
public class LoggerInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle( HttpServletRequest request,
    HttpServletResponse response, Object handler) throws Exception {
        ...
        return true;
    }

}

the main difference between HandlerInterceptor and HandlerInterceptorAdapter is that in the first one we need to override all three methods: preHandle(), postHandle() and afterCompletion(), whereas in the second we may implement only required methods.

MVC View

1. Add an InternalResourceViewResolver (by name)

** Simple strategy for DispatcherServlet to resolve views: Just by name

2. Add an XmlViewResolver

3. Add a ResourceBundleViewResolver

Spring MVC also supports multiple view resolvers.

The order property is used to define which is the order of invocations in the chain. The higher the order property (largest order number), the later the view resolver is positioned in the chain

ContentNegotiatingViewResolver, is an interesting view resolver, which allow you to output a same resource (content or data) to different type of views like JSP, XML, RSS, JSON and etc.

  1. http://www.mkyong.com/fruit/banana.rss , returned as RSS file.
  2. http://www.mkyong.com/fruit/banana.xml , returned as XML file.
  3. http://www.mkyong.com/fruit/banana.json , returned as JSON file.
  4. http://www.mkyong.com/fruit/banana, returned to your default view resolver.

Content type resolution order

  1. Path extension against the mediaType map e.g. html maps to text/html
  2. Path extension against FileTypeMap in Java Activation Framework.
  3. Use HTTP Accept header of the request

MVC Model

Simply put, the model can supply attributes used for rendering views.To provide a view with usable data, we simply add this data to its Model object. Additionally, maps with attributes can be merged with Model instances:

@GetMapping("/showViewPage")
public String passParametersWithModel(Model model) {
    Map<String, String> map = new HashMap<>();
    map.put("spring", "mvc");
    model.addAttribute("message", "Baeldung");
    model.mergeAttributes(map);
    return "viewPage";
}

Just like the Model interface above, ModelMap is also used to pass values to render a view. The advantage of ModelMap is it gives us the ability to pass a collection of values and treat these values as if they were within a Map :

@GetMapping("/printViewPage")
public String passParametersWithModelMap(ModelMap map) {
    map.addAttribute("welcomeMessage", "welcome");
    map.addAttribute("message", "Baeldung");
    return "viewPage";
}

JavaScript async call to only get domain data back and **render the corresponding portion of the HTML

Lec 5 : Persistence and Object-Relational Mapping

Persistence definition: persistence refers to the characteristic of a state that outlives the process that created it. Without this capability, states would only exist in RAM, and would be lost when RAM loses power, such as a computer shutdown.

Relational database definition: a database that stores information about both the data and how it is related. Data and relationships are represented in a flat, two-dimensional table that preserves relational structuring.

Java Database Connectivity (JDBC): Set of standard APIs to access relational databases, Support creating and executing SQL statements CREATE, INSERT, UPDATE and DELETE, or Query statements such as SELECT, which return a JDBC row result set

DAO: the Data Access Object design pattern: separates data access logic from business logic and presentation logic, CRUD (Create, Read, Update, and Delete) encapsulated in an independent module

Dao interface

DAO with JDBC

Datasource configuration

  • New connection on every request
  • One connection only: no concurrency
  • Pooled connections
    • Initial and max connection size
    • Database Connection Pooling Services (DBCP) module of the Apache

JDBC steps

  • Obtain a database connection from the data source
  • Create a PreparedStatement object from the connection
  • Bind the parameters to the PreparedStatement object
  • Execute the PreparedStatement object
  • Handle SQLException
  • Clean up the statement object and connection

Update a Database with a Statement Setter

SQL Statement and Parameter Values

Extract data with a row mapper

ORM: Automate JDBC

Manually writing all the code for each entity is getting tedious, like SQL, connection, mapping, Let the ORM (Object Relational Mapping) framework do it for you

  • Specify the object⇒ DB mapping
  • Declare the transactional constraints

JDBC, Hibernate, JPA

JPA vs JDO: JPA supports any datastore, JPO supports RDBMs only

Hibernate XML Mappings

The <class> elements are used to define specific mappings from a Java classes to the database tables. The Java class name is specified using the name attribute of the class element and the database table name is specified using the table attribute.

The <id> element maps the unique ID attribute in class to the primary key of the database table. The name attribute of the id element refers to the property in the class and the column attribute refers to the column in the database table. The type attribute holds the hibernate mapping type, this mapping types will convert from Java to SQL data type.

The <property> element is used to map a Java class property to a column in the database table. The name attribute of the element refers to the property in the class and the column attribute refers to the column in the database table. The type attribute holds the hibernate mapping type, this mapping types will convert from Java to SQL data type.

DAO in Hibernate

JPA Annotations

DAO with JPA

Configure JPA templates

DAO implementation with JPA templates

JDBC v.c. JPA

  • ORM (access patterns: JPA, Hibernate)
  • SQL (access patterns: JDBC, Spring JDBC)

ORMs are used to map your RDBMS tables and records to Java objects. They're used to transfer state between your RDBMS and Java in a completely transparent way, getting SQL out of the way, which is incredibly useful once CRUD becomes complex. CRUD can become complex when, within a single transaction, you want to add/remove/enhance/link/unlink dozens of different entities, resulting in potentially hundreds of SELECT, INSERT, UPDATE, DELETE statements, avoiding unnecessary locking at all costs. For this: Use ORMs (e.g. via JPA).

SQL is used to model complex bulk data processing, denormalising your stored schema into various different formats, via joins, unions, hierarchical queries, etc. This is extremely useful when doing complex querying, reporting, batch operations, and much more. For this: Use SQL (e.g. via JDBC).

Lec 6 : Advanced ORM

Composite Primary Key by @IdClass

Must override the equals and hashCode function.

@Entity @IdClass(ProjectId.class)

public class Project {
    @Id int courseId;
    @Id String projectName;
    …
}

Class ProjectId {

int courseId;

String projectName;
    ...

public boolean equals(Object o) { … }

public int hashCode() { … }
}

ProjectId id = new ProjectId(3,
“AOP”);

Project prj =
em.find(ProjectId.class, id);

System.out.println("courseId = " +
proj.getCourseId() + " projectName
= " + prj.getProjectName()”;

Composite Primary Key by @EmbeddedId

@Entity
public class Project {
    @EmbeddedId
    ProjectId id;
    …
}
@Embeddable
Class ProjectId {
    int courseId;
    String projectName;
    ...

public boolean equals(Object o) { … }
    public int hashCode() { … }
}

HQL Difference

With @IdClass select p.courseId from Project as p

With @EmbeddedId select p.id.courseId from Project as p

OneToOne Mapping

ManyToOne Mapping

OneToMany Mapping

ManyToMany Mapping

This association has two sides i.e. the owning side and the inverse side. In our example, the owning side is Employee so the join table is specified on the owning side by using the @JoinTable_annotation in _Employee class. The @JoinTable is used to define the join/link table. In this case, it is Employee_Project.

Embeddable types

Historically Hibernate called these components. JPA calls them embeddables. Either way the concept is the same: a composition of values. For example we might have a Name class that is a composition of first-name and last-name, or an Address class that is a composition of street, city, postal code, etc.

_Usage of the word embeddable :_To avoid any confusion with the annotation that marks a given embeddable type, the annotation will be further referred as @Embeddable

Embeddable objects

  • No tables, no IDs
  • Cannot be directly persisted or queried

Inheritance and Persistence

Relational databases have no concept of inheritance

Single Table Inheritance

  • Put the whole hierarchy in one table
  • One column for every attribute of every class
  • Discriminator column to determine which class the particular row belongs to
    • Each class in the hierarchy has its own unique discriminator value

Joined, Multiple Table Inheritance

  • Mirrors the object model
    • A table is defined for each class for local attributes
    • Each table must also store the object's id (primary key), which is only defined in the root class
    • A discriminator column is used to determine which class the particular row belongs to
    • Each class in the hierarchy defines its own unique discriminator value.

Table per class

results matching ""

    No results matching ""