Spring @Autowired not working
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.
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)?
Important points:
- Sometimes, @Component may leads to a problem where it might say no default constructor found. The class which is defined as a @Component annotation, it must have a default constructor.
- Suppose, we have applied @Autowired annotation at field which is a user defined class reference. Now, if we also apply @Component to that class then it will always be initialized with null. So, a field with @Autowired should not have @Component at its class definition.
- By default @Autowired is byType.
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