Difference between <context:annotation-config/> vs <context:component-scan/>:
<context:annotation-config/> : <context:annotation-config/> is used to activate all the annotations that are present in java beans and those are already registered using application context file or being registered while component scanning (annotations). The main point is they need to be registered.
<context:component-scan/> : <context:component-scan/> scan packages and classes within given base packages then it find and register beans into ApplicationContext. It does all things that <context:annotation-config/> is supposed to do.
Example:
From the below example you will see the difference between <context:annotation-config/> and <context:component-config/>. Here I'm taking 3 Beans for reference.
I've created below 3 classes
Employee.java
package com.evon;
import org.springframework.beans.factory.annotation.Autowired;
public class Employee {
private int id;
private String name;
@Autowired
private DepartmentA departmentA;
@Autowired
private DepartmentB departmentB;
public Employee(){
System.out.println("Employee Created");
}
public DepartmentA getDepartmentA() {
return departmentA;
}
public void setDepartment(DepartmentA departmentA) {
System.out.println("Setting DepartmentA");
this.departmentA = departmentA;
}
public DepartmentB getDepartmentB() {
return departmentB;
}
public void setDepartmentB(DepartmentB departmentB) {
System.out.println("Setting DepartmentB");
this.departmentB = departmentB;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
DepartmentA.java
package com.evon;
public class DepartmentA {
private String name;
public DepartmentA(){
System.out.println("DepartmentA Created");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
DepartmentB.java
package com.evon;
public class DepartmentB {
private String name;
public DepartmentB(){
System.out.println("DepartmentB Created");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
App.java class is used to load and initialize the application context:
App.java
package com.app;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.evon.Department;
import com.evon.Employee;
public class App {
/**
* @param args
*/
public static void main(String[] args) {
ApplicationContext ctx=new ClassPathXmlApplicationContext(new String[]{"app-context.xml"});
}
}
1- I'm injecting DepartmentA and DepartmentB into Employee in below configuration:
app-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="departmentA" class="com.evon.DepartmentA"></bean>
<bean id="departmentB" class="com.evon.DepartmentB"></bean>
<bean id="superUser" class="com.evon.Emplyee">
<property name="departmentA" ref="departmentA"></property>
<property name="departmentB" ref="departmentB"></property>
</bean>
</beans>
Output:-
Employee Created
DepartmentA Created
DepartmentB Created
Setting DepartmentA
Setting DepartmentB
2- Now we'll use annotation in our bean. As you notice Emplyee.java, I've used @Autowired annotation for wiring the properties. So now I'm removing the properties injection from configuration.
app-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="departmentA" class="com.evon.DepartmentA"></bean>
<bean id="departmentB" class="com.evon.DepartmentB"></bean>
<bean id="superUser" class="com.evon.Emplyee"></bean>
</beans>
Output:-
Employee Created
DepartmentA Created
DepartmentB Created
From the above output as you can see that properties injection didnt take place only the new beans were created. This is because, in spring by default annotations dont do anything by themselves , if you want to use them you have to enable them in your application.
3- Now to enable annotations you just need to write the below line in your context file:
<context:annotation-config/>
Now the updated app-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
<bean id="departmentA" class="com.evon.DepartmentA"></bean>
<bean id="departmentB" class="com.evon.DepartmentB"></bean>
<bean id="superUser" class="com.evon.Emplyee"></bean>
</beans>
Output:-
Employee Created
DepartmentA Created
DepartmentB Created
Setting DepartmentA
Setting DepartmentB
4- Now remove the bean declarations from the Xml file and use @Component annotation to register it as a bean. Here are the updated files.
app-context.xml :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
</beans>
Employee.java
package com.evon;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Employee {
private int id;
private String name;
@Autowired
private DepartmentA departmentA;
@Autowired
private DepartmentB departmentB;
public Employee(){
System.out.println("Employee Created");
}
public DepartmentA getDepartmentA() {
return departmentA;
}
public void setDepartment(DepartmentA departmentA) {
System.out.println("Setting DepartmentA");
this.departmentA = departmentA;
}
public DepartmentB getDepartmentB() {
return departmentB;
}
public void setDepartmentB(DepartmentB departmentB) {
System.out.println("Setting DepartmentB");
this.departmentB = departmentB;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
DepartmentA.java
package com.evon;
import org.springframework.stereotype.Component;
@Component
public class DepartmentA {
private String name;
public DepartmentA(){
System.out.println("DepartmentA Created");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
DepartmentB.java
package com.evon;
import org.springframework.stereotype.Component;
@Component
public class DepartmentB {
private String name;
public DepartmentB(){
System.out.println("DepartmentB Created");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//No Output
<context:annotation-config /> activate the annotations only on beans which have already been discovered and registered. As <context:annotation-config /> is not sufficient and cant register beans marked with @Component annotation.
5- So, now we'll need to declare component scan, it will scan all the packages provided as an argument to it and will register all the beans marked @Component annotation , and once the bean is registered it <context:annotation-config /> will inject them.
As <context:component-scan/> scan packages and classes within given base packages then it find and register beans into ApplicationContext. It does all things that <context:annotation-config/> is supposed to do.
So if you have used annotation for example, @Autowired in your code and in xml then You do not require to use <context:annotation-config/>. So we can remove <context:annotation-config /> from our configuration file.
Updated app-context.xml :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.evon"/>
</beans>
Now when I executed App.java class , all the 3 beans have been created and been injected properly.
Output:-
Employee Created
DepartmentA Created
DepartmentB Created
Setting DepartmentA
Setting DepartmentB
Hope this will help you :)
0 Comment(s)