What is the difference between @Component and @Bean in Spring ?
Key | @Bean | @Component |
Auto detection | It is used to do a explicit declaration of a single bean, rather than letting Spring do it automatically. This is similar to putting <bean id=””> in spring-config.xml. | It is implicit declaration of the bean. If any class is annotated with @Component it will automatically be detect by using classpath scan. |
Spring Container | Bean can be created even if class is outside the spring container | We can’t create bean if class is outside spring container |
Class/Method Level Annotation | It is a method level annotation | It is a class level annotation |
@Configuration | It works only when class is also annotated with @Configuration | It works without @Configuration annotation |
Use Case | We should use @bean, if you want specific implementation based on dynamic condition. | We can’t write specific implementation based on dynamic condition |
Library | Generally its used to add 3rd party library to your code. | Generally its used to have your own component to your code. |
As explained in the previous example I am writing down again the @Bean usage:
Have a bean called Book.java, this should contain the business methods. For simplicity I had kept only setters and getters.
package com.heapsteep.model; public class Book { private String bookName; public void setBookName(String bookName) { this.bookName = bookName; } public String getBookName() { return bookName; } }
Then have a configuration java file. Here we have injected values to it :
@Configuration public class MyConfig { @Bean(name="book") public Book book() { Book book=new Book(); book.setBookName("Ramayana"); return book; } }
Now we are having the actual client class where we are using the bean :
public class SpringDemo_WithoutXML { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class); Book book = (Book)context.getBean("book"); System.out.println("Book Name>>>:"+ book.getBookName()); context.registerShutdownHook(); } }
So guys we have explained above how to use the @Bean annotations.
Now lets convert the above code and see how to use the @Component annotations.
We declared the spring bean there itself we make it @Component and there itself we injected values to it:
package com.heapsteep.model; import org.springframework.stereotype.Component; @Component public class Book{ private String bookName; public String getBookName() { bookName="HeapSteep"; return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } }
And now we are having the client class and we are using that bean:
package com.heapsteep; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.heapsteep.model.Book; import com.heapsteep.Book2; public class SpringDemo_WithoutXML { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.scan("com.heapsteep"); context.refresh(); Book book=(Book)context.getBean(Book.class); System.out.println("------####" + book.getBookName()); context.registerShutdownHook(); } }
- See how we are doing the “Component-Scan” by the scan() . This is mandatory to tell the container which package to look for.
- See the other changes by yourself.
P.S: @component and its specializations(@controller, @service, @repository) allow for auto-detection using classpath scanning. If we see component class like @Controller, @service, @repository will be scan automatically by the spring framework using the component scan.