Spring @Autowired not working

后端 未结 7 1950
再見小時候
再見小時候 2021-02-08 12:35

I have some problems wth autowire annotation. My app looks like this:

Here is controller:

@Controller
public class MyController {
    @Autowired
    @Qua         


        
相关标签:
7条回答
  • 2021-02-08 12:45

    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.

    0 讨论(0)
  • 2021-02-08 12:48

    Important points:

    1. 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.
    2. 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.
    3. 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

    0 讨论(0)
  • 2021-02-08 12:51

    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)?

    0 讨论(0)
  • 2021-02-08 12:56

    There can be two reasons for this.

    1. When you have not annotated the injected object or say service with proper @Service/@Component/@Repository annotations.

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

    0 讨论(0)
  • 2021-02-08 12:57

    I guess you need <context:annotation-config />.

    0 讨论(0)
  • 2021-02-08 13:00

    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.

    0 讨论(0)
提交回复
热议问题