简体   繁体   中英

@Autowired class from service cannot be resolved to a type in controller class

I am very new to spring boot and I cant for the life of my figure out why my @Autowired FarmService class from service cannot be resolved to a type in controller class. My application class is a package level above the service and controller class.

This is the hierarchy of the packages

FarmApplication.java code:

package prac.farm;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan
public class FarmApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(FarmApplication.class, args);
    }

}

FarmController.java code:

package prac.farm.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class FarmController {
    
    @Autowired
    private FarmService farmservice;
    
    @RequestMapping(value = "/home", method = RequestMethod.GET)
    public String display() {
        return farmservice.getOwner();
    }

}

FarmService.java code:

package prac.farm.service;

import org.springframework.stereotype.Service;

@Service
public class FarmService {
    private String owner;
    private String location;
    private int yearsOwned;
    
    public FarmService() {
        super();
        this.owner = "alale";
        this.location = "Uppsa";
        this.yearsOwned = 2;
    }
    
//  public FarmService(String owner, String location, int yearsOwned) {
//      super();
//      this.owner = owner;
//      this.location = location;
//      this.yearsOwned = yearsOwned;
//  }
    
    public String getOwner() {
        return owner;
    }
    public void setOwner(String owner) {
        this.owner = owner;
    }
    public String getLocation() {
        return location;
    }
    public void setLocation(String location) {
        this.location = location;
    }
    public int getYearsOwned() {
        return yearsOwned;
    }
    public void setYearsOwned(int yearsOwned) {
        this.yearsOwned = yearsOwned;
    }


}

First of all, @ComponentScan is redundant as @SpringBootApplication already includes this annotation. Secondly, you don't seem to import the FarmService class in your controller.

So I think your confusion comes from the gap between what you've heard about Spring as a dependency injection framework and your compiler giving you this error.

The key thing about Spring is that it only acts on runtime . If you really think about what the compiler is telling you, it makes a lot of sense. You have this class called FarmService that you haven't imported, so from the point of view of the compiler, FarmController knows nothing about what a FarmService is and what methods it has.

So if you need to put the import statement, doesn't that just add it as a dependency and defeat the whole point of using spring in the first place, when we're trying to loosen the coupling? The solution is an interface.

Create an interface called FarmService and use that in your controller class. Then rename your current class FarmServiceImpl that implements that interface. You do not need to import the implementation. When Spring runs, it will autowire the implementation. In this way, you have no explicit dependency on the implementation in your code but it will still be used during runtime.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM