Spring @Component Annotation Example

0

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.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.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.

You can download the source code here: springComponentAnnotationExample.zip
Share.

Comments are closed.