Java configuration
@Configuration
@Configuration
@PropertySource("classpath:example.properties")
public class ApplicationConfiguration {
@Bean
public MessageBean getMessageBean() {
return new HelloWorldBean();
}
@Bean(name = "message")
public String getMessage( @Value("${bean.message}") String message) {
return message;
}
}
Usage
public class SpringApplicationMain {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ApplicationConfiguration.class);
MessageBean messageBean = applicationContext.getBean(MessageBean.class);
System.out.println("->" + messageBean.getMessage());
}
}
Tests
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = ApplicationConfiguration.class)
public class ApplicationConfigurationTest {
public static final String MESSAGE = "this is a bean";
/**
* Complex example with the use of annotations and autowire
*/
@Autowired
ApplicationContext applicationContext;
@Autowired
MessageBean messageBean;
@Test
public void testApplicationContext() {
Assertions.assertNotNull(applicationContext);
MessageBean messageBean = applicationContext.getBean(MessageBean.class);
Assertions.assertEquals(MESSAGE, messageBean.getMessage());
}
}
Configuration
Configuration metadata, contains bean definitions, can use Import to import other configurations.
@Import({Configuration.class,OtherConfiguration.class})
PropertySource
Adds additional properties, prefixes (“classpath”,”file” and “http”).
@PropertySource(“classpath:/com/example/example.properties”)
@PropertySource(“file:config/example.properties”)
Tests
To configure Spring context in Spring a combination of annotations can be used.
Configures Junit to use Spring Context, can use @ContextConfiguration to set configuration class. @ContextConfiguration(classes = ApplicationConfiguration.class)
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = ApplicationConfiguration.class)
public class AutoWiringTypesTest {
@Autowired
@Qualifier("fruitSaladConstructor")
FruitSaladConstructor fruitSaladConstructor;
....
}
Annotations @ExtendWith and @ContextConfiguration can be replaced with @SpringJUnitConfig or @SpringJUnitWebConfig.
@SpringJUnitConfig(SpringJUnitConfigIntegrationTest.Config.class)
public class SpringJUnitConfigIntegrationTest {
@Configuration
static class Config {}
}
Annotation configuration
Using @ComponentScan and stereotypes.
@Configuration
@PropertySource("classpath:example.properties")
@ComponentScan
public class ApplicationConfiguration {
...
...
...
@Service
public class SomeService {
@Value("${service.message}")
private String message = "";
public String getMessage() {
return message;
}
}
Autowired
Usage of @Autowired
Constructor injection
@Autowired
public TransferServiceImpl(AccountRepository repository){..}
Method
@Autowired
public void setAccountRepository(AccountRepository)
Field injection (discouraged)
@Autowired
private AccountRepository accountRepository;
By default autowired beans are required but this be changed: @Autowired(required=false)
Optional is also supported:
@Autowired
public void setAccountService(Optional<AccountService> optAccountService){..}
Disambiguation
@Qualifier is used for disambiguation, can be used both for components and beans (names).
@Autowired
public TransferServiceImpl(@Qualifier("jdbc") AccountRepository ar){ ..}
@Component("jdbc")
public class MyJDBCAccountRepositoryImp{
..}
Autowiring resolution rules:
- look for unique bean of request type
- use @Qualifier if present
- try to find bean matching by name
Configuration choices
If a class has only a default constructor -> no need to annotate with @Autowired
if class had only one non-default constructor -> no need to annotate with @Autowired
if class has more than one constructor -> Spring will call zero-argument by default or @Autowired must be used
Constructor vs setter
Constructor – mandatory dependencies – dependencies can be immutable – concise | Setter – can allow for circular dependencies – dependencies are mutable – can be verbose – inherit automatically |
Lazy beans
Lazy beans can be useful when the component is not available at startup, are created when:
- dependency is injected
- calling ApplicationContext.getBean()
@Component("myService")
@Lazy(true)
public class MyServiceImpl implements MyService{
...
}
@Configuration
public class ApplicationConfig{
@Autowired
@Lazy(true)
public MyService getMyService(){
..
}
}