`@Autowired` 类在控制器类中无法解析为类型。

huangapple go评论75阅读模式
英文:

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

问题

我对Spring Boot非常陌生但我始终无法弄清楚为什么我的控制器类中的@Autowired FarmService类无法解析为一种类型我的应用程序类位于服务和控制器类的包级别之上

这是包的层次结构

FarmApplication.java 代码

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 代码

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 代码

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;
    }

}
英文:

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

`@Autowired` 类在控制器类中无法解析为类型。

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;
}
}

答案1

得分: 1

首先,@ComponentScan 是多余的,因为 @SpringBootApplication 已经包含了这个注解。其次,在你的控制器中似乎没有导入 FarmService 类。

英文:

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.

答案2

得分: 0

所以我认为你的困惑源于你听说过 Spring 是一个依赖注入框架,但你的编译器却给你返回了这个错误。

关于 Spring 的关键是它只在运行时起作用。如果你真正思考一下编译器告诉你的信息,它就会很有意义。你有一个叫做 FarmService 的类没有被导入,所以从编译器的角度来看,FarmController 对于 FarmService 是一无所知的,也不了解它有哪些方法。

所以,如果你需要添加导入语句,这难道不会将它作为一个依赖项添加进来,并且从根本上违背了使用 Spring 的初衷吗?因为我们试图降低耦合度。解决方案是使用一个接口。

创建一个名为 FarmService 的接口,并在你的控制器类中使用它。然后将你当前的类命名为实现该接口的 FarmServiceImpl。你不需要导入实现。当 Spring 运行时,它会自动装配这个实现。通过这种方式,你的代码中没有对实现的显式依赖,但它在运行时仍然会被使用。

英文:

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.

huangapple
  • 本文由 发表于 2020年9月4日 17:30:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/63738505.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定