I have some problems wth autowire annotation. My app looks like this:
Here is controller:
@Controller
public class MyController {
@Autowired
@Qua
You should include this section of XML code in spring-config.xml
:
<context:component-scan base-package="Fully.Qualified.Package.Name" />
but you should know the difference between <context:annotation-config>
vs <context:component-scan>
as most people are suggesting these two :
1) First big difference between both tags is that <context:annotation-config>
is used to activate applied annotations in already registered beans in application context. Note that it simply does not matter whether bean was registered by which mechanism e.g. using <context:component-scan>
or it was defined in application-context.xml
file itself.
2) Second difference is driven from first difference itself. It does register the beans in context + it also scans the annotations inside beans and activate them. So <context:component-scan>
; does what <context:annotation-config>
does, but additionally it scan the packages and register the beans in application context.
Important points:
Address bean is autowired at Student class. Let’s see what happens if we apply @Component at Address.java.
CollegeApp.java:
package com.myTest
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import com.bean.Address;
import com.bean.Student;
//Component scanning will for only those classes
//which is defined as @Component. But, all the class should not use
//@Component always even if the class is enabled with auto
//component scanning, specially the class which is Autowired
//Or which is a property of another class
@Configuration
@ComponentScan(basePackages={"com.bean"})
public class CollegeApp {
@Bean
public Address getAddress(){
return new Address("Elgin street");
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(CollegeApp.class);
Student student=context.getBean(Student.class);
System.out.println(student.toString());
context.close();
}
}
We want Elgin street to be autowired with Student address.
Address.java:
package com.bean;
import org.springframework.stereotype.Component;
@Component
public class Address {
private String street;
public Address()
{
}
public Address(String theStreet)
{
street=theStreet;
}
public String toString()
{
return (" Address:"+street);
}
}
Student.java:
package com.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Student {
private String name;
private int age;
private Address address;
public Student()
{
}
public Student(String theName,int theAge)
{
name=theName;age=theAge;
}
@Autowired
public void setAddress(Address address) {
this.address = address;
}
public String toString()
{
return ("Name:"+name+" Age:"+age+ " "+address);
}
}
Output: - Name:null Age:0 Address:null //Address not Autowired here.
To resolve the issue, only change the Address.java as below:
Address.java:
package com.bean;
public class Address {
private String street;
public Address(String theStreet)
{
street=theStreet;
}
public String toString()
{
return (" Address:"+street);
}
}
Output:- Name:null Age:0 Address:Elgin street
I found the solution. As Javi said (thanks a lot for you, Javi), I have to annotate DAO and Service layer classes with @Repository
and @Service
annotation. Now I've tried to write like this:
@Service("someService")
public class SomeServiceImpl implements SomeService{
@Autowired
@Qualifier("myDAO")
private MyDAO myDAO;
....
}
and
@Repository("myDAO")
public class JDBCDAOImpl implements MyDAO {
@Autowired
@Qualifier("dataSource")
private DataSource dataSource;
....
}
and all works fine!!!
But I still not found an answer for this quesion: if application will be more complex, and will have more complex structure, where @Repositore
and @Service
annotation are not preferred for some classes, how to inject correctly beans, which located in lower levels (in a fields of classes, or in a field of fields of classes) (with @Autowire
annotation, of course)?
There can be two reasons for this.
When you have not annotated the injected object or say service with proper @Service/@Component/@Repository annotations.
Once you have made sure of point 1 ,next check for whether the class package of your annotated service class is included in the class-path for your spring boot application in the main class.You can configure this using the following annotation.
@SpringBootApplication(scanBasePackages = { "com.ie.efgh.somepackage","com.ie.abcd.someotherpackage" })
Doing this you tell spring to look into the packages for the classes during class loading.
I guess you need <context:annotation-config />
.
You can use
<context:component-scan base-package="PATH OF THE BASE PACKAGE"/>
entry in your configuration .xml file. This entry will scan/read all the stated type and annotations from the java classes.