In this article “Spring @Component Annotation Example” we are going to discuss. If a class is annotated with @Component
then it becomes a candidate for auto-detection as we create an annotation based context or use a classpath scanning to register components. The component name can be specified through the annotation’s value. If the name is not specified then the decapitalized version of class name will be used as the bean name.
In this article, we will see examples of @Component
annotation.
BeanA:
package com.javarticles.spring.annotations; import org.springframework.stereotype.Component; @Component("thisIsBeanA") public class BeanA { }
We now need to build the application context using the @Configuration
and @Component
annotated classes.
We will first create the annotation based application context.
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
Next, we need to register all the annotated classes or at least one annotated class that can further trigger a component scan or import specific annoated classes.
ctx.register(SpringComponentAnnotationExample.class); ctx.refresh();
In our example, we register SpringComponentAnnotationExample
which is annotated with @Component
and @ComponentScan
. @ComponentScan
will further scan the package where SpringComponentAnnotationExample
is residing. If you want to scan some other packages, specify them using basePackages
attribute.
If there are no base packages specified then scanning will occur from the package of the class with this annotation, in our case, com.javarticles.spring.annotations
.
SpringComponentAnnotationExample:
package com.javarticles.spring.annotations; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.stereotype.Component; @Component @ComponentScan public class SpringComponentAnnotationExample { public static void main(String[] args) { System.setProperty("spring.profiles.active", "component"); AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); try { ctx.register(SpringComponentAnnotationExample.class); ctx.refresh(); System.out.println("SpringComponentAnnotationExample: " + ctx.getBean("springComponentAnnotationExample")); System.out.println("BeanA: " + ctx.getBean("thisIsBeanA")); } finally { ctx.close(); } } }
As you can see BeanA
also gets registered.
Output:
Jan 20, 2016 12:10:45 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org.spring[email protected]7106e68e: startup date [Wed Jan 20 12:10:45 IST 2016]; root of context hierarchy Jan 20, 2016 12:10:45 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.s[email protected]4ec6a292: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,springComponentAnnotationExample,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,thisIsBeanA,springConfigurationAnnotationExample]; root of factory hierarchy SpringComponentAnnotationExample: com.[email protected]3327bd23 BeanA: [email protected] Jan 20, 2016 12:10:45 PM org.springframework.context.support.AbstractApplicationContext doClose INFO: Closing org.spring[email protected]7106e68e: startup date [Wed Jan 20 12:10:45 IST 2016]; root of context hierarchy Jan 20, 2016 12:10:45 PM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons INFO: Destroying singletons in org.s[email protected]4ec6a292: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,springComponentAnnotationExample,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,thisIsBeanA,springConfigurationAnnotationExample]; root of factory hierarchy
Inner Static Component “@component annotation”
We can also define a static inner class as a component. Default bean name of the inner static class would be decapitalized name of the outer class + “.” + Inner class name. For example, to get the bean of inner static class BeanB.InnerBeanB
, it would be:
ctx.getBean("beanB.InnerBeanB")
BeanB:
package com.javarticles.spring.annotations; import org.springframework.stereotype.Component; @Component public class BeanB { @Component public static class InnerBeanB { } }
We will modify the main class to get beans of BeanB
and its inner static class BeanB.InnerBeanB
.
SpringComponentAnnotationExample:
package com.javarticles.spring.annotations; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.stereotype.Component; @Component @ComponentScan public class SpringComponentAnnotationExample { public static void main(String[] args) { System.setProperty("spring.profiles.active", "component"); AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); try { ctx.register(SpringComponentAnnotationExample.class); ctx.refresh(); System.out.println("SpringComponentAnnotationExample: " + ctx.getBean("springComponentAnnotationExample")); System.out.println("BeanA: " + ctx.getBean("thisIsBeanA")); System.out.println("BeanB: " + ctx.getBean("beanB")); System.out.println("beanB.InnerBeanB: " + ctx.getBean("beanB.InnerBeanB")); } finally { ctx.close(); } } }
Output:
Jan 20, 2016 7:28:30 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org.spring[email protected]7106e68e: startup date [Wed Jan 20 19:28:30 IST 2016]; root of context hierarchy Jan 20, 2016 7:28:30 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.s[email protected]4ec6a292: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,springComponentAnnotationExample,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,thisIsBeanA,beanB.InnerBeanB,beanB,springConfigurationAnnotationExample]; root of factory hierarchy SpringComponentAnnotationExample: com.[email protected]3327bd23 BeanA: [email protected] BeanB: [email protected] beanB.InnerBeanB: [email protected] Jan 20, 2016 7:28:30 PM org.springframework.context.support.AbstractApplicationContext doClose INFO: Closing org.spring[email protected]7106e68e: startup date [Wed Jan 20 19:28:30 IST 2016]; root of context hierarchy Jan 20, 2016 7:28:30 PM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons INFO: Destroying singletons in org.s[email protected]4ec6a292: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,springComponentAnnotationExample,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,thisIsBeanA,beanB.InnerBeanB,beanB,springConfigurationAnnotationExample]; root of factory hierarchy
Difference between @Component and @Configuration
@Configuration
classes are just like regular @Components
classes as @Configuration
is meta-annotated with @Component
.
... @Component public @interface Configuration { ... }
When the class containing @Configuration
or @Component
contains @Bean
annotated methods, those methods act as factory beans so what is the difference? The difference lies in the inter-bean references when one @Bean
method invokes another @Bean
method. If the class is annotated with @Component
the @Bean
method invocation is treated as a standard Jav amethod invocation whereas when a @Bean
method declared in @Configuration
is called the method invocation is intercepted using CGLIB proxy and the bean cached in the spring container is returned.
When a @Bean
annotated method owned by the @Component
class is called the method is simply re-invoked and we will get a new bean at each invocation rather than returning the one cached in the container. When @Bean
methods are re-invoked @Configuration
annotation is preferred.
In the below example, we have class TestBeanAsComponent
annotated with @Component
and TestBeanAsConfiguration
annotated with @Configuration
.
Both classes have the same @Bean
method beanC()
which returns a bean of class C
.
Since both methods create the bean instance for the same class, we have used @Profile
so that one doesn’t override other.
Here is a simple class C
which we will register using the factory method annotated with @Bean
.
C:
package com.javarticles.spring.annotations; public class C { }
TestBeanAsComponent:
package com.javarticles.spring.annotations; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; @Component("testBean") @Profile("component") public class TestBeanAsComponent { @Autowired private BeanA beanA; @Autowired private BeanB beanB; public BeanA getBeanA() { return beanA; } public BeanB getBeanB() { return beanB; } @Bean public C beanC() { return new C(); } }
SpringComponentAnnotationExample:
package com.javarticles.spring.annotations; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.stereotype.Component; @Component @ComponentScan public class SpringComponentAnnotationExample { public static void main(String[] args) { System.setProperty("spring.profiles.active", "component"); AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); try { ctx.register(SpringComponentAnnotationExample.class); ctx.refresh(); System.out.println("SpringComponentAnnotationExample: " + ctx.getBean("springComponentAnnotationExample")); System.out.println("BeanA: " + ctx.getBean("thisIsBeanA")); System.out.println("BeanB: " + ctx.getBean("beanB")); System.out.println("beanB.InnerBeanB: " + ctx.getBean("beanB.InnerBeanB")); System.out.println("BeanC: " + ctx.getBean("beanC")); TestBeanAsComponent testBean = (TestBeanAsComponent) ctx.getBean("testBean"); System.out.println("BeanA from testBean: " + testBean.getBeanA()); System.out.println("BeanB from testBean: " + testBean.getBeanB()); System.out.println("BeanC from testBean: " + testBean.beanC()); } finally { ctx.close(); } } }
As you can see the bean cached in the container and the bean invoked by calling beanC()
method are both different instances.
Output:
Jan 20, 2016 7:36:49 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org.springframework.conte[email protected]: startup date [Wed Jan 20 19:36:49 IST 2016]; root of context hierarchy Jan 20, 2016 7:36:49 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.s[email protected]4ec6a292: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,springComponentAnnotationExample,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,thisIsBeanA,beanB.InnerBeanB,beanB,springConfigurationAnnotationExample,testBean,beanC]; root of factory hierarchy SpringComponentAnnotationExample: com.[email protected]3327bd23 BeanA: [email protected] BeanB: [email protected] beanB.InnerBeanB: [email protected] BeanC: [email protected] BeanA from testBean: [email protected] BeanB from testBean: [email protected] BeanC from testBean: [email protected] Jan 20, 2016 7:36:49 PM org.springframework.context.support.AbstractApplicationContext doClose INFO: Closing org.spring[email protected]7106e68e: startup date [Wed Jan 20 19:36:49 IST 2016]; root of context hierarchy Jan 20, 2016 7:36:49 PM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons INFO: Destroying singletons in org.s[email protected]4ec6a292: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,springComponentAnnotationExample,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,thisIsBeanA,beanB.InnerBeanB,beanB,springConfigurationAnnotationExample,testBean,beanC]; root of factory hierarchy
Let’s now try the same with @Configuration
annotated class. @component annotation
TestBeanAsConfiguration:
package com.javarticles.spring.annotations; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; @Configuration("testBean") @Profile("configuration") public class TestBeanAsConfiguration { @Autowired private BeanA beanA; @Autowired private BeanB beanB; public BeanA getBeanA() { return beanA; } public BeanB getBeanB() { return beanB; } @Bean public C beanC() { return new C(); } }
SpringConfigurationAnnotationExample:
package com.javarticles.spring.annotations; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.stereotype.Component; @Component @ComponentScan public class SpringConfigurationAnnotationExample { public static void main(String[] args) { System.setProperty("spring.profiles.active", "configuration"); AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); try { ctx.register(SpringConfigurationAnnotationExample.class); ctx.refresh(); System.out.println("SpringConfigurationAnnotationExample: " + ctx.getBean("springConfigurationAnnotationExample")); System.out.println("BeanA: " + ctx.getBean("thisIsBeanA")); System.out.println("BeanB: " + ctx.getBean("beanB")); System.out.println("BeanC: " + ctx.getBean("beanC")); System.out.println("beanB.InnerBeanB: " + ctx.getBean("beanB.InnerBeanB")); TestBeanAsConfiguration testBean = (TestBeanAsConfiguration) ctx.getBean("testBean"); System.out.println("BeanA from testBean: " + testBean.getBeanA()); System.out.println("BeanB from testBean: " + testBean.getBeanB()); System.out.println("BeanC from testBean: " + testBean.beanC()); } finally { ctx.close(); } } }
You can see the bean cached in the container and the bean invoked by calling beanC()
method are both same.
Output:
Jan 20, 2016 7:38:24 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org.spring[email protected]7106e68e: startup date [Wed Jan 20 19:38:24 IST 2016]; root of context hierarchy Jan 20, 2016 7:38:24 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.s[email protected]4ec6a292: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,springConfigurationAnnotationExample,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,thisIsBeanA,beanB.InnerBeanB,beanB,springComponentAnnotationExample,testBean,beanC]; root of factory hierarchy SpringConfigurationAnnotationExample: com.java[email protected]45820e51 BeanA: [email protected] BeanB: [email protected] BeanC: [email protected] beanB.InnerBeanB: [email protected] BeanA from testBean: [email protected] BeanB from testBean: [email protected] BeanC from testBean: [email protected] Jan 20, 2016 7:38:24 PM org.springframework.context.support.AbstractApplicationContext doClose INFO: Closing org.spring[email protected]7106e68e: startup date [Wed Jan 20 19:38:24 IST 2016]; root of context hierarchy Jan 20, 2016 7:38:24 PM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons INFO: Destroying singletons in org.s[email protected]4ec6a292: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,springConfigurationAnnotationExample,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,thisIsBeanA,beanB.InnerBeanB,beanB,springComponentAnnotationExample,testBean,beanC]; root of factory hierarchy
Registering Annotation Based Classes Via XML
Define component scanning using <context:component-scan>
element, specify the base package using base-package
.
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> <context:component-scan base-package="com.javarticles.spring.annotations"/> </beans>
Since the context i sdriven using component scanning declared in XML, use ClassPathXmlApplicationContext
to create context.
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
SpringComponentAnnotationLoadedViaXMLExample:
package com.javarticles.spring.annotations; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.stereotype.Component; @Component @ComponentScan public class SpringComponentAnnotationLoadedViaXMLExample { public static void main(String[] args) { System.setProperty("spring.profiles.active", "component"); ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); try { System.out.println("SpringComponentAnnotationExample: " + ctx.getBean("springComponentAnnotationExample")); System.out.println("BeanA: " + ctx.getBean("thisIsBeanA")); System.out.println("BeanB: " + ctx.getBean("beanB")); System.out.println("beanB.InnerBeanB: " + ctx.getBean("beanB.InnerBeanB")); System.out.println("BeanC: " + ctx.getBean("beanC")); TestBeanAsComponent testBean = (TestBeanAsComponent) ctx.getBean("testBean"); System.out.println("BeanA from testBean: " + testBean.getBeanA()); System.out.println("BeanB from testBean: " + testBean.getBeanB()); System.out.println("BeanC from testBean: " + testBean.beanC()); } finally { ctx.close(); } } }
Output:
Jan 20, 2016 7:40:50 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org[email protected]179d3b25: startup date [Wed Jan 20 19:40:50 IST 2016]; root of context hierarchy Jan 20, 2016 7:40:50 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [applicationContext.xml] Jan 20, 2016 7:40:50 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.s[email protected]5e5792a0: defining beans [thisIsBeanA,beanB.InnerBeanB,beanB,springComponentAnnotationExample,springComponentAnnotationLoadedViaXMLExample,springConfigurationAnnotationExample,testBean,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,beanC]; root of factory hierarchy SpringComponentAnnotationExample: com.[email protected]e320068 BeanA: [email protected] BeanB: [email protected] beanB.InnerBeanB: [email protected] BeanC: [email protected] BeanA from testBean: [email protected] BeanB from testBean: [email protected] BeanC from testBean: [email protected] Jan 20, 2016 7:40:50 PM org.springframework.context.support.AbstractApplicationContext doClose INFO: Closing org[email protected]179d3b25: startup date [Wed Jan 20 19:40:50 IST 2016]; root of context hierarchy Jan 20, 2016 7:40:50 PM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons INFO: Destroying singletons in org.s[email protected]5e5792a0: defining beans [thisIsBeanA,beanB.InnerBeanB,beanB,springComponentAnnotationExample,springComponentAnnotationLoadedViaXMLExample,springConfigurationAnnotationExample,testBean,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,beanC]; root of factory hierarchy
Download the source code “@component annotation”
This was an example about Spring @Component Annotation.