code what my question is about:
@SpringBootApplication
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String args[]) {
SpringApplication.run(Application.class);
}
@Bean
public Object test(RestTemplate restTemplate) {
Quote quote = restTemplate.getForObject(
"http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
log.info(quote.toString());
return new Random();
}
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
@Bean
public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
return args -> {
Quote quote = restTemplate.getForObject(
"http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
log.info(quote.toString());
};
}
}
I'm very new to Spring. As far as I understood the @Bean annotation is responsible that an Object is saved in a IoC container, correct?
If so: Are first all Methods with @Bean collected and then executed?
In my example I added a method test() what does the same as run() but returns an Object (Random()) instead. The result is the same so it is working with CommandLineRunner and Object.
Is there a Reason why it should return a CommandLineRunner i.e. use the syntax like run()?
Moreover: At that point I don't see so far the advantage to move methods to an container. Why not just execute it?
Thank you!
CommandLineRunner is a simple Spring Boot interface with a run method. Spring Boot will automatically call the run method of all beans implementing this interface after the application context has been loaded.
Interface CommandLineRunner This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference. Interface used to indicate that a bean should run when it is contained within a SpringApplication .
ApplicationRunner takes ApplicationArgument which has convenient methods like getOptionNames(), getOptionValues() and getSourceArgs(). CommandLineRunner run() will get execute, just after applicationcontext is created and before spring boot application starts up.
One of the most important annotations in spring is the @Bean annotation which is applied on a method to specify that it returns a bean to be managed by Spring context. Spring Bean annotation is usually declared in Configuration classes methods. This annotation is also a part of the spring core framework.
@Configuration
classes (@SpringBootApplication
extends @Configuration
) are the place where the spring beans are registered.
@Bean
is used to declare a spring bean. The method that is annotated with @Bean
has to return an object(the bean). By default the spring beans are singletons, so once the method annotated with @Bean
is executed and returns it's value this object lives til the end of the application.
In your case
@Bean
public Object test(RestTemplate restTemplate) {
Quote quote = restTemplate.getForObject(
"http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
log.info(quote.toString());
return new Random();
}
this will produce s singleton bean of type Random with name 'test'. So if you try to inject (e.g. with @Autowire
) a bean of that type or name in other spring bean you will get that value. So this is not a good use of @Bean
annotation, unless you want exactly that.
CommandLineRunner
on the other hand is a special bean that lets you execute some logic after the application context is loaded and started. So it makes sense to use the restTemplate here, call the url and print the returned value.
Not long ago the only way to register a Spring bean was with xml. So we had an xml files and bean declarations like this:
<bean id="myBean" class="org.company.MyClass">
<property name="someField" value="1"/>
</bean>
The @Configuration
classes are the equivalent of the xml files and the @Bean
methods are the equivalent of the <bean>
xml element.
So it's best to avoid executing logic in bean methods and stick to creating objects and setting their properties.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With