liveBook · Manning

Java configuration

As explained in Spring in Action, Sixth Edition

Application configuration specified directly by the developer rather than inferred automatically by the framework.

Java configuration tells Spring directly which objects to manage and how to connect them. Mark a class with @Configuration and its bean-producing methods with @Bean. Spring adds each returned object to the application context; by default, its bean ID matches the method name. This is the Java alternative to declaring the same relationships in XML. section 1.1

@Configuration
public class ServiceConfiguration {
  @Bean
  public InventoryService inventoryService() {
    return new InventoryService();
  }
 
  @Bean
  public ProductService productService() {
    return new ProductService(inventoryService());
  }
}

The service configuration creates an InventoryService, then passes it to a ProductService constructor. Both become Spring-managed beans. section 1.1

You usually need less configuration than this. Component scanning can discover components, autowiring can supply their dependencies, and Spring Boot can configure much of an application automatically. Write Java configuration when those defaults do not provide what the application needs. Compared with XML, Java configuration offers greater type safety and is easier to refactor. section 1.1

Customize application security

Suppose an application needs registered users, its own login page, and different access rules for different request paths. Those requirements go beyond the initial Spring Security defaults, so explicit configuration is needed. A small first step is a @Configuration class with a @Bean method returning a BCryptPasswordEncoder. That bean can be used when creating users and checking passwords at login. section 5.1 section 5.2

Listing 5.1 A barebones configuration class for Spring Security
package tacos.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
 
@Configuration
public class SecurityConfig {
 
  @Bean
  public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
  }
 
}

The security configuration listing shows the complete class and its PasswordEncoder bean. The method returns a BCryptPasswordEncoder rather than leaving encoder creation to automatic configuration. section 5.2

Java configuration can also define a Spring Integration flow. A @Transformer bean can receive text from one channel and send uppercase text to another; a @ServiceActivator bean can pass that result to a file-writing handler. The named channels can be created automatically, so they do not have to be declared as beans. If an existing flow is defined in XML instead, @ImportResource can bring that resource into a Java configuration class. section 10.1.2 section 10.1.1

Listing 10.3 Using Java configuration to define an integration flow
package sia6;
 
import java.io.File;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.annotation.Transformer;
import org.springframework.integration.file.FileWritingMessageHandler;
import org.springframework.integration.file.support.FileExistsMode;
import org.springframework.integration.transformer.GenericTransformer;
 
@Configuration
public class FileWriterIntegrationConfig {
 
  @Bean
  @Transformer(inputChannel="textInChannel",              #1
               outputChannel="fileWriterChannel")
  public GenericTransformer<String, String> upperCaseTransformer() {
    return text -> text.toUpperCase();
  }
 
  @Bean
  @ServiceActivator(inputChannel="fileWriterChannel")
  public FileWritingMessageHandler fileWriter() {         #2
    FileWritingMessageHandler handler =
        new FileWritingMessageHandler(new File("/tmp/sia6/files"));
    handler.setExpectReply(false);
    handler.setFileExistsMode(FileExistsMode.APPEND);
    handler.setAppendNewLine(true);
    return handler;
  }
 
}

The file-writer listing puts the transformer and file-writing handler in one configuration class. Its annotations connect the two stages through named channels. section 10.1.2

How Spring in Action, Sixth Edition covers it

How deep it goes
Works through annotated bean methods and security and integration configurations, while leaving automatically handled components to Spring.
Examples
Uses two constructor-wired services, a BCrypt password encoder, and an uppercase-to-file integration flow.
What it assumes
Introduces @Configuration, @Bean, and the application context while using readable Java classes and methods as examples.
What you can do after
Apply it via Spring annotations to declare beans and customize security or integration behavior beyond automatic defaults.
How it connects
Connects bean wiring with the application context, autowiring, component scanning, Spring Boot autoconfiguration, Spring Security, and Spring Integration.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Spring in Action, Sixth Edition. The section links point to the parts of the book it draws on.