Close

Dependency Injection, black magic or a must have tool for a modern Java application?

If you have passed your courses about object oriented programming, you know that loose coupling is something you should always strive for. There are many ways to achieve loose coupling. Inversion of control (IoC) using dependency injection (DI) is one way to improve the quality of your code.

When a developer asks me how they should build a “full-stack application”, I pretty much always suggest basing their application either on Java EE or Spring. One of the reasons is the DI containers that both technology stacks provide. Many developers and architects are a bit afraid of this “magic” that inversion of control and dependency injection bring in, often for the wrong reasons.

Last week we had a webinar with my colleague Petter Holmström about dependency injection. If you want to get an idea of what dependency injection is or just want to refresh your knowledge of the subject, you should definitely check it out. In the webinar we discuss if, why and when you should use dependency injection in your applications and go through the basic principles and alternatives.

The key takeaways of our webinar:

  • Loose coupling and high cohesion (and all the advantages they bring) are the main things we aim for with DI.

  • When starting with DI, learn the basic concepts well and watch out for the pitfalls. Otherwise the DI container will cause you more harm than good.

  • Contexts and events will further help you create reusable and maintainable code.

  • There is no need to bring in “all the magic” of the Spring or Java EE technology stacks. I like to use DI even in the simplest cases because Vaadin CDI and Vaadin Spring make it easier to use Vaadin compared to the plain servlet approach and setting everything up yourself.

  • There are multiple DI containers to choose from. Vaadin has integrations for three of them:

  • There are also alternative mechanisms that you can use if you for some reason aren’t able to use a DI container. Simply by designing your code using IoC patterns, you can achieve loose coupling and high cohesion.

Our Java EE training also discusses DI and how to use it in your Vaadin applications. If you want more hands on training about dependency injection, join our next course!

Learn more about Vaadin Trainings

Vaadin Support heroes in action

A typical day at Vaadin Support: tell us your problem, we give you the solution. We help with a huge variety of issues. Every customer has their specific circumstances which creates a challenge to our support heroes daily. However, we did solve a few generic problems recently and I’d like to share these with you. Maybe you’ve been struggling with these topics, too. 

Setting a 24 hr time format for PopupDateField

A customer had an issue that they had tried to solve by themselves without success. They were wondering how to set 24 hr time format for the PopupDateField irrespective of the current locale. The answer was straightforward, but to get to the solution, our expert needed to dig some source code of Vaadin Framework. Here’s how you do it. 

You need to override UI.getLocaleService() to return a custom version of LocalService where createLocaleData is overridden. Here you can set the 24 hr format on and off. 

@Override
protected LocaleData createLocaleData(Locale locale) {
    LocaleData createLocaleData = super.createLocaleData(locale);
    createLocaleData.twelveHourClock = false;
    return createLocaleData;
}

Drag’n drop in Table doesn’t behave as expected

One of our customers needed a better drag’n drop behavior for the Table component. As it happens, Table doesn’t scroll its contents properly when reordering rows by drag’n drop. Like, moving a row to the top of a long list. The customer sponsored a few hours of development time and now it’s available as an Add-on named DNDScroll. Later our support team member implemented the same functionality for the Panel component too, as a Community effort. These enhancements are now available for everyone. If this is something you need for Table or Panel, go ahead and download the DNDScroll Add-on from Vaadin Directory

File upload requirements

Our support expert got the task to enhance and customise the upload component. The EasyUploads add-on was a good basis, but lacked some of the desired features. We delivered customer specific functionality for look’n feel, document previews and localisation but also introduced enhancements that are available for everyone. Now the EasyUploads Add-on offers configuration options for limited MIME types and a maximum number of files to be uploaded. If this is what you need, please go and download the EasyUploads Add-on from Vaadin Directory

We are here to help anyone with a Vaadin related problem, big or small. If you aren’t sure if this is something for you, check out the how support saves you money below. 

Read how Support saves time and money

Vaadin + jOOQ: Implementing Business Web Applications in Plain Java

Note: This post has been updated to use Vaadin 8.

When speaking about business applications, you might find that a lot of them fall into the “data-centric” kind of application where SQL is frequently the key technology. Similarly, when speaking about web applications, you’ll end up with HTML rendered on the browser, most likely with the help of JavaScript. If we put this into the context of Java, web business applications can be implemented by directly using SQL, HTML, JavaScript, and of course Java. Vaadin and jOOQ enable you to implement data-centric web applications using only one language: Java.

This step by step guide shows you how to implement a Spring-based web application that connects to a MySQL server in order to query data that can be filtered from the UI. This guide assumes you know the very basics of Maven and Spring Framework (particularly the concept of dependency injection).

Step 1: Create a Spring-based project

Create a new Spring Boot application by going to http://start.spring.io and adding the Vaadin, jOOQ, and MySql dependencies as shown in the following figure:

Screen Shot 2016-10-04 at 14.38.32.pngClick the Generate Project button and extract the generated zip file. You should get a Maven project you can import into your favorite IDE.

Step 2: Create a MySQL database

Connect to the MySQL instance and create a new schema:

CREATE SCHEMA demo;

Create the following table:

CREATE TABLE customer(
    id SERIAL, first_name VARCHAR(255),
    last_name VARCHAR(255)
);

Add some test data, such as the following:

INSERT INTO customer(first_name, last_name) VALUES('Lukas', 'Eder');
INSERT INTO customer(first_name, last_name) VALUES('Mario', 'Fusco');
INSERT INTO customer(first_name, last_name) VALUES('Edson', 'Yanaga');
INSERT INTO customer(first_name, last_name) VALUES('Anton', 'Arhipov');
INSERT INTO customer(first_name, last_name) VALUES('Andres', 'Almiray');

Step 3: Configure the database connection

jOOQ allows you to reverse-engineer the database into a set of Java classes modeling the tables, sequences, and stored procedures, among other database objects.

Start by configuring the database connection in the application.properties file inside the src/main/resources directory:

spring.datasource.url=jdbc:mysql://localhost/demo
spring.datasource.username=user
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jooq.sql-dialect=MySQL

Remember to change the username and password used to connect to your own database.

Step 4: Reverse-engineer the database

Add the Properties Maven plugin and the jOOQ Code Generator plugin for Maven in the plugins section of the pom.xml file:

<plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>properties-maven-plugin</artifactId>
   <version>1.0.0</version>
   <executions>
       <execution>
           <phase>initialize</phase>
           <goals>
               <goal>read-project-properties</goal>
           </goals>
           <configuration>
               <files>
                   <file>src/main/resources/application.properties</file>
               </files>
           </configuration>
       </execution>
   </executions>
</plugin>
<plugin>
   <groupId>org.jooq</groupId>
   <artifactId>jooq-codegen-maven</artifactId>
   <version>3.8.4</version>
   <executions>
       <execution>
           <goals>
               <goal>generate</goal>
           </goals>
       </execution>
   </executions>
   <configuration>
       <jdbc>
           <url>${spring.datasource.url}</url>
           <user>${spring.datasource.username}</user>
           <password>${spring.datasource.password}</password>
           <driver>${spring.datasource.driver}</driver>
       </jdbc>
       <generator>
           <database>
               <name>org.jooq.util.mysql.MySQLDatabase</name>
               <inputSchema>demo</inputSchema>
           </database>
           <target>
               <packageName>com.example</packageName>
               <directory>target/generated-sources/jooq</directory>
           </target>
       </generator>
   </configuration>
</plugin>

The previous snippet uses the connection properties defined in the application.properties file to avoid duplicating this configuration. Make sure the <inputSchema> element contains the name of the MySQL database you previously created.

Run the following Maven command:

    mvn clean install

This will reverse-engineer the database and generate the corresponding Java classes in the target/generated-sources/jooq/ directory.

Note that if you are using Eclipse, you have to give it an extra “hint” for it to pick the generated sources directory and not to complain about missing “m2e connectors”.

Step 5: Create a back-end service class

Create the following CustomerService class:

package com.example;

import com.example.tables.records.CustomerRecord;
import org.jooq.DSLContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

import static com.example.Tables.*;

@Component
public class CustomerService {

    @Autowired
    private DSLContext dslContext;

    public List<CustomerRecord> searchByName(String name) {
        String filter = name + "%";
        return dslContext
            .selectFrom(CUSTOMER)
            .where(CUSTOMER.FIRST_NAME.likeIgnoreCase(filter)
            .or(CUSTOMER.LAST_NAME.likeIgnoreCase(filter)))
            .fetchInto(CustomerRecord.class);
    }
}

Spring Boot will automatically create a bean of type DSLContext that you can use to query the database using plain Java but in a way that resembles SQL. Visit the official documentation site of jOOQ for more information about the capabilities of its API.

Step 6: Implement the UI

Create a Vaadin UI by implementing the VaadinUI class:

package com.example;

import com.example.tables.records.CustomerRecord;
import com.vaadin.server.VaadinRequest;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.ui.Grid;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

@SpringUI
public class VaadinUI extends UI {

    @Autowired
    private CustomerService service;

    private Grid<CustomerRecord> grid = new Grid(CustomerRecord.class);

    @Override
    protected void init(VaadinRequest vaadinRequest) {
        TextField filter = new TextField("Filter by name:");
        filter.addValueChangeListener(e -> updateGrid(filter.getValue()));

        VerticalLayout layout = new VerticalLayout(filter, grid);
        setContent(layout);
        updateGrid("");
        grid.setColumns("firstName", "lastName");
    }

    private void updateGrid(String filter) {
        List<CustomerRecord> customers = service.searchByName(filter);
        grid.setItems(customers);
    }

}

This class creates a UI containing a Grid component to show all the customers in the database and a filter to search by first or last name. Notice how the VaadinUI class is annotated with @SpringUI. This means we can inject the CustomerService bean in this class and use it to fetch customers.

Step 7: Run the application

Spring Initializr created the Application class with a standard main method defining the entry point of the Java application. When you run the application using this method, Spring Boot configures and runs a Tomcat server on port 8080 (all this can be configured).

Before running the application you have to build it. You can use the following command to build and run the application:

    mvn install spring-boot:run

The following is a screenshot of the application:

Screen Shot 2016-10-04 at 16.50.49.png

Check out the full jOOQ + Vaadin example from GitHub