Getting Spring Certified 3 | Reviewing the Study guide
By: Micheal Arsenault
Posted: December 26, 2020| Modified: January 5, 2021
Reading Time: 7 minutes
Tags: certification Java Spring
resources:
What is the preferred way to close an application context? Does Spring Boot do this for you?
NON-WEB CONTEXT
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public final class Boot {
public static void main(final String[] args) throws Exception {
ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
// add a shutdown hook for the above context...
ctx.registerShutdownHook();
// app runs here...
// main method exits, hook is called prior to the app shutting down...
}
}
It’s important to note here the ‘Boot’ class here has nothing to do with Spring Boot. This will link the application to the JVM and upon JVM shutdown the ApplicationContext to close.
Additionally, there is a close() function that will close the application context and destroy al of it’s beans as well. Additionally this will remove a JVM linked shutdown hook if one is registered.
If you’re using Spring to create a web based application it will link itself with the container in order to shutdown properly; otherwise you’ll need to register a shutdown hook yourself.
Spring-Boot shutdown Hook
Spring boot’s SpringApplication itself registers a shutdown hook with the JVM. There’s also the capability for an application to create a bean that implements the ExitCodeGenerator Interface. In the below example from Spring’s Boot documentation you can see
@SpringBootApplication
public class ExitCodeApplication {
@Bean
public ExitCodeGenerator exitCodeGenerator() {
return () -> 42;
}
public static void main(String[] args) {
System.exit(SpringApplication.exit(SpringApplication.run(ExitCodeApplication.class, args)));
}
}
WEB Hooks
Spring integrates the ApplicationContext lifecycle with the web application itself so no manual steps are needed for the web application context.
Next part of the study guide has multiple sections:
Can you describe:
* Dependency injection using Java configuration?
* Dependency injection using annotations (@Autowired)?
* Component scanning, Stereotypes?–Scopes for Spring beans?
* What is the default scope?
I want to take a second and mention how I don’t like the question above. It mentions using “Java configuration” and then mentions “using annotations”; this to me is a bit confusing as annotations are Java code. Regardless, I keep this in my head as thinking of the distinction of using Java class(es) as a central place to create Spring beans. I also will be splitting up some of the above questions based upon how large these posts become.
Dependency injection using Java configuration?
Java configuration would look like below. You can see that we’re explicitly instantiating the beans inside of the methods.
@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer
propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
@Profile("test")
UserRepo userRepoTest() {
return new HashMapUserRepo();
}
@Bean
@Profile("test")
Greeter greeterTest(@Value("${greeting.test}") String greeting) {
return new GreeterImpl(greeting);
}
@Bean
@Profile("prod")
Greeter greeterProd(@Value("${greeting.prod}") String greeting) {
return new GreeterImpl(greeting);
}
@Bean
@Profile("prod")
UserRepo prodRepo() {
return new HashMapUserRepo();
}
}
While the above code is calling methods like normal, it’s important to understand that by using the @Configuration annotation you’re explicitly telling Spring to intercept method calls using Spring’s AOP methods. This means beans are still created in a prototype like fashion regardless of the actual usage of the method being called. So if you call any method you’ll only really be given the same object each time. Additionally, if you don’t use the @Configuration annotation on a class then you’ll have different effects when creating @Bean methods especially on intr-bean calls.
I’ve also included the below example from the documentation where they have a simple configuration class:
@Configuration
public class AppConfig {
@Bean
public BeanOne beanOne() {
return new BeanOne(beanTwo());
}
@Bean
public BeanTwo beanTwo() {
return new BeanTwo();
}
}
It’s also important to think of Java annotation like XML configuration when it comes to integrating multiple disparate sources into a unified area. This means that you can have one Java configuration that will pull in XML files, as well as other @Configuration annotated classes
@Configuration
public class ServiceConfig {
@Bean
public TransferService transferService(AccountRepository accountRepository) {
return new TransferServiceImpl(accountRepository);
}
}
@Configuration
public class RepositoryConfig {
@Bean
public AccountRepository accountRepository(DataSource dataSource) {
return new JdbcAccountRepository(dataSource);
}
}
@Configuration
@Import({ServiceConfig.class, RepositoryConfig.class})
public class SystemTestConfig {
@Bean
public DataSource dataSource() {
// return new DataSource
}
}
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SystemTestConfig.class);
// everything wires up across configuration classes...
TransferService transferService = ctx.getBean(TransferService.class);
transferService.transfer(100.00, "A123", "C456");
}
- Injecting Dependencies on Imported @Bean Definitions
- You can see here that we’re pulling in configuration metadata from other classes, but this could just as easily have been XML documents
- Really one of the major points to understand, is that with this you’re able to create a central repository where you instantiate and setup objects to be used throughout your application.
Alright, this has gone on long enough and I’ll begin with this next: Dependency injection using annotations (@Autowired)