Skip to content

Spring Integration Framework Code Style

Artem Bilan edited this page Nov 14, 2022 · 4 revisions

Introduction

This document defines the coding standards for source files in the Spring Integration Framework. It is primarily intended for the Spring Integration Framework team but can be used as a reference by contributors.

The structure of this document is based on the Google Java Style reference and is work in progress.

Code conventions you can pick up for your IDE from the Spring Framework templates in the project source: InteglliJ IDEA or Eclipse.

Source File Basics

File encoding: UTF-8

Source files must be encoded using UTF-8.

Indentation

  • Indentation uses tabs (not spaces)
  • Unix (LF), not DOS (CRLF) line endings.
  • For Windows users, the Git client can be configured for the autocrlf = true option.
  • Eliminate all trailing whitespace
    • On Linux, Mac, etc.: find . -type f -name "*.java" -exec perl -p -i -e "s/[ \t]$//g" {} \;

Source file structure

A source file consists of the following, in this exact order:

  • License
  • Package statement
  • Import statements
  • Exactly one top-level class

Exactly one blank line separates each of the above sections.

License

Each source file must specify the following license at the very top of the file:

/*
 * Copyright 2016-2022 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

Make sure to run the tests for modified code before pushing and Gradle updateCopyrights task will update all the modified class for the current year.

Import statements

The import statements are structured as follow:

  • import java.*
  • blank line
  • import javax.*
  • import jakarta.*
  • blank line
  • import all other imports
  • blank line
  • import org.springframework.*
  • blank line
  • import static all other imports

Also, static imports should not be used in production code. They should be used in test code, especially for things like org.junit.Assert. Plus no one asterisk (*) import is allowed.

Java source file organization

The following governs how the elements of a source file are organized:

  1. static fields
  2. normal fields
  3. constructors
  4. (private) methods called from constructors
  5. static factory methods
  6. JavaBean properties (i.e., getters and setters)
  7. method implementations coming from interfaces
  8. private or protected templates that get called from method implementations coming from interfaces
  9. other methods
  10. equals, hashCode, and toString

Note that private or protected methods called from method implementations should be placed immediately below the methods where they're used. In other words if there 3 interface method implementations with 3 private methods (one used from each), then the order of methods should include 1 interface and 1 private method in sequence, not 3 interface and then 3 private methods at the bottom.

Above all, the organization of the code should feel natural.

Formatting

Braces

Block-like constructs: K&R style

Braces mostly follow the Kernighan and Ritchie style (a.k.a., "Egyptian brackets") for nonempty blocks and block-like constructs:

  • No line break before the opening brace but prefixed by a single space
  • Line break after the opening brace
  • Line break before the closing brace
  • Line break after the closing brace if that brace terminates a statement or the body of a method, constructor, or named class with the exception of the else, catch and finally statements that also lead to a line break

Example:

return new MyClass() {
    @Override 
    public void method() {
        if (condition()) {
            something();
        }
        else {
            try {
                alternative();
            } 
            catch (ProblemException ex) {
                recover();
            }
        }
    }
};

Line wrapping: around 120 characters

Aim to wrap code and Javadoc at 120 characters but favor readability over wrapping as there is no deterministic way to line-wrap in every situation.

When wrapping a lengthy expression put the separator symbol at the end of the line, rather on the next line (think comma separated arguments as an example). For instance:

if (thisLengthyMethodCall(param1, param2) && anotherCheck() &&
        yetAnotherCheck()) {
....
}

Blank Lines

Add two blank lines before the following elements:

  • static {} block
  • Fields
  • Constructors
  • Inner classes

Add one blank line after a method signature that is multiline, i.e.

@Override
protected Object invoke(FooBarOperationContext context, 
        AnotherSuperLongName name) {

    // code here
}

Add one blank line before the class closing curly bracket.

Add one blank line in the end of each file (not only Java classes).