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
