0

I am fairly new to Java so sorry if this is not well described. I was initially able to get the Student list to appear in localhost:8080/api/v1/student when the list was in the StudentController file.

But for best practice, it was advised that it is good to split the files into Controller and Service files and move the list into the StudentService.java file, which is what I did, but now I am receiving an error saying:

APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in com.example.demo.student.StudentController required a bean of type 'com.example.demo.student.StudentService' that could not be found.


Action:

Consider defining a bean of type 'com.example.demo.student.StudentService' in your configuration.


Process finished with exit code 1

The error specifies "Consider defining a bean of type 'com.example.demo.student.StudentService' in your configuration" but the error doesn't say which file this is specified.

Other similar Stackoverflow questions have solutions that involve import @Component or importing something. I think it may be due to a missing import so I tried adding 'import com.example.demo.student.StudentService' into the StudentController.java file but I'm still getting the error so I've just removed the import line. The files are below.. thanks!

DemoApplication.java

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class DemoApplication {

    public static void main(String[] args) {

        SpringApplication.run(DemoApplication.class, args);
    }
}

StudentController.java

package com.example.demo.student;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

// @RestController makes the bellow class serve Rest endpoints (@GetMapping)
@RestController
@RequestMapping(path = "api/v1/student")
public class StudentController {
    //reference
    private final StudentService studentService;
    // add to constructor
    public StudentController(StudentService studentService) {
        // Initializing Private Final StudentService variable
        this.studentService = studentService;
    }

    //In order for ths method to be served as a RESTful endpoint, we annotate with:
    @GetMapping
    //We now have a GetMapping for Studentcontroller
    public List<Student> getStudents() {
        return studentService.getStudents();
    }
}

StudentService.java

package com.example.demo.student;

import java.time.LocalDate;
import java.time.Month;
import java.util.List;

public class StudentService {
    public List<Student> getStudents() {
        return List.of(
                new Student(
                        1L,
                        "Mariam",
                        "mariam.jamal@gmail.com",
                        LocalDate.of(2000, Month.JANUARY, 5),
                        21
                )
        );
    }
}
RedRum
  • 902
  • 1
  • 13
  • 26
  • 3
    Annotate your `StudentService` with `@Service`. – void void Oct 15 '22 at 19:20
  • ahah that worked! I guess the '''@RestController '''in the StudentController.java file is the equalivent of '''@Service''' in the StudentService! The tutorial I'm following doesn't mention '''@Service'''! many thanks! – RedRum Oct 15 '22 at 19:26

2 Answers2

2

You can use @Component or @Service annotation over you service class to tell Spring IOC container to create bean of it.

Then you can use @Autowired annotation in your Component class to inject the bean of your service class.

Here is the updated code of it -

Controller Class -

package com.example.demo.student;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

// @RestController makes the bellow class serve Rest endpoints (@GetMapping)
@RestController
@RequestMapping(path = "api/v1/student")
public class StudentController {
    //reference
    @Autowired
    private final StudentService studentService;
    // add to constructor
    public StudentController() {
 
    }

    //In order for ths method to be served as a RESTful endpoint, we annotate with:
    @GetMapping
    //We now have a GetMapping for Studentcontroller
    public List<Student> getStudents() {
        return studentService.getStudents();
    }
}

Service Class -

package com.example.demo.student;

import java.time.LocalDate;
import java.time.Month;
import java.util.List;

@Service
public class StudentService {
    public List<Student> getStudents() {
        return List.of(
                new Student(
                        1L,
                        "Mariam",
                        "mariam.jamal@gmail.com",
                        LocalDate.of(2000, Month.JANUARY, 5),
                        21
                )
        );
    }
}
Aman Mehta
  • 303
  • 1
  • 12
  • ```@Component``` also worked and ```@Autowried``` is something new I'll have to research, thanks! – RedRum Oct 15 '22 at 19:31
0

Regarding to answer of @void void I want to add a few option on your spring knowledge. when you create any instance of the classes in project you must annotate it prototype annotation in spring boot, otherwise you face a problem, which you see. Spring must know on own container where programmer define beans them? @Service @Repository @RestController are prototype annotation in spring boot keep it mind!