Skip to content

Component Diagram Backend

vanpeerdevelopment edited this page Jan 15, 2016 · 5 revisions

Component Diagram - Backend

The backend is built with Spring Boot and has layered architecture. Each layer is responsible for a specific set of tasks as described in the next sections.

Infrastructure

The infrastructure layer is responsible for the integration with the database and for managing the application properties. This is configured in its Spring JavaConfig file InfrastructureConfig.

The default properties are read using @PropertySource from a file on the classpath. It is possible to override the default properties defined in dws.default.properties by passing a property on application startup java -jar -Ddb.host=dws_db_acc:5432. All properties will be available in Environment.

Communication with the database is done using JDBI, which is a wrapper for JDBC providing a more user-friendly API. In InfrastructureConfig the datasource, transactionmanager as well as dbi are configured. All JDBC dependencies are loaded using the spring-boot-starter-jdbc dependency.

At last the infrastructure layer is responsible for scanning all the Spring beans defined in the this layer by using @ComponentScan.

/* InfrastructureConfig.java */
package be.cegeka.dws.infrastructure.spring;

import ... 

@Configuration
@PropertySource("classpath:/dws.default.properties")
@ComponentScan("be.cegeka.dws.infrastructure")
public class InfrastructureConfig {

    @Inject
    private Environment environment;

    @Bean
    public DataSource dataSource() {
        PoolConfiguration poolConfiguration = new PoolProperties();
        ...
        return new org.apache.tomcat.jdbc.pool.DataSource(poolConfiguration);
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }

    @Bean
    public DBI dbi() {
        return new DBI(dataSource());
    }
}

Domain

The domain layer contains all the domain classes and repositories. The Spring configuration is done in DomainConfig. The domain config will scan all Spring beans and will define Spring beans for all repositories. The repositories are manually defined as bean because JDBI's SQL Object API is used in the project. This makes it possible to declaratively define all queries on interface methods. The dbi.ondemand(...) method will return an object with the API defined in the according interface. Obtaining and releasing connections will be done automatically.

/* DomainConfig.java */
package be.cegeka.dws.domain.spring;

import ...

@Configuration
@ComponentScan("be.cegeka.dws.domain")
public class DomainConfig {

    @Inject
    private DBI dbi;

    @Bean
    public PetRepository petRepository() {
        return dbi.onDemand(PetRepository.class);
    }
}

Service

The service layer provides access to the domain and is the start point for transactions. The ServiceConfig is rather simple and will just scan the entire service layer for Spring beans.

/* ServiceConfig.java */
package be.cegeka.dws.service.spring;

import ...

@Configuration
@ComponentScan("be.cegeka.dws.service")
public class ServiceConfig {
}

Rest

The rest layer provides an API to the frontend to retrieve pets and set up dates. The REST resources are implemented using Jersey which is loaded by the spring-boot-starter-jersey dependency. The RestConfig will register all Spring beans defined in the rest layer and will load the Jersey configuration.

/* RestConfig.java */
package be.cegeka.dws.rest.spring;

import ...

@Configuration
@ComponentScan("be.cegeka.dws.rest")
public class RestConfig {

    @Bean
    public JerseyConfig jerseyConfig() {
        return new JerseyConfig();
    }
}
/* JerseyConfig.java */
package be.cegeka.dws.rest.spring;

import ...

@ApplicationPath("/api")
public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        packages("be.cegeka.dws.rest");
    }
}

To make an executable jar providing the REST API defined in the rest layer it is necessary to load the spring-boot-maven-plugin. This plugin will make a fat jar containing all the projects dependencies and will search for a main method in the project and configure it as Main-Class to start the jar. The main class for DWS will import all Spring JavaConfigs to bootstrap the Spring application context. Each layer is responsible for loading and scanning all things in its own layer. Starting the jar will start an embedded tomcat which will listen on port 8080 for incoming requests.

/* Application.java */
package be.cegeka.dws.rest.spring;

import ...

@Import({
        InfrastructureConfig.class,
        DomainConfig.class,
        ServiceConfig.class,
        RestConfig.class
})
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}