How to add @Repository to non-controller class in Spring?

Viewed 215

I'm working on a simple Spring Boot application that creates and stores XML files that contain customer licensing information.

But now I would like to add a separate module which imports similar XML files (which were created previously) into the app's database. For that, I need to use the same repository which is used in the app's controller. The repository gets passed into the controller's constructor as follows:

@RestController
@RequestMapping("/api")
class LicenseController {

    private LicenseRepository licenseRepository;
    private UserRepository userRepository;

    public LicenseController(LicenseRepository licenseRepository,
                             UserRepository userRepository) {
        this.licenseRepository = licenseRepository;
        this.userRepository = userRepository;
    }

Presumably, the controller annotation informs Spring-Boot to pass repositories to the constructor. However, the separate module used for import isn't a controller, it's just a POJO with a main class.

How do I get the license repository into this POJO?

3 Answers

Mark your POJO as @Component and DI with constructor will be allowed for LicenseRepository as in the code above.

@Component // or @Service | @Repository | @Controller
class YourPOJO {
   private LicenseRepository licenseRepository;

   public YourPOJO(LicenseRepository licenseRepository) {
        this.licenseRepository = licenseRepository;
    }
}

Create a Business Object(BO) class rather than a normal POJO or DTO where you can have a custom method to pass repository from your custom Controller.

But still I would consider it as a bad design because DAO actions are never performed in BO, DTO and POJO as their works are totally different. I would tell you to find a way to do it in some other way.

For the requirement, this design can be picked up for now.

For example:

@RestController
@RequestMapping("/api")
class LicenseController {

    @Autowired
    private LicenseRepository licenseRepository;

    @Autowired
    private UserRepository userRepository;

    @RequestMapping(value="/license", method=RequestMethod.POST)
    public void storeLicense() {
    
      SimpleBO bo = new SimpleBO(); 
      bo.doSomethingWithLicenseRepository(licenseRepository);
      // do stuff 

    }

}

Now, create an example SimpleBO class.

public class SimpleBO {

  private String someField;
   
  public SimpleBO() {
    super(); 
  } 

  public void doSomethingWithLicenseRepository(LicenseRepository licenseRepository) {
     .....
  }

  // getter and setters and toString() method.


}

I think this will be ok for you.

Package scan and will initialize its instance by calling the @Autowired annotated constructor.

@Service
public class UserLicenseService {
     
    private final LicenseRepository licenseRepository;
    private final UserRepository userRepository;
    
    public UserLicenseService (LicenseRepository licenseRepository, UserRepository userRepository) {
        this.licenseRepository = licenseRepository;
        this.userRepository = userRepository;
    }

    // ...
}

Controller.

@RestController
@RequestMapping("/api")
class LicenseController {

    @Autowired
    private UserLicenseService userLicenseService;

    @RequestMapping(value="/license", method = RequestMethod.POST)
    public void storeLicense() {
    
      // using UserLicenseService.

    }

}

Main.

ApplicationContext context = SpringApplication.run(YourMainApplication.class, args);
UserLicenseService userLicenseService = context.getBean(UserLicenseService.class);

// using UserLicenseService.

using-boot-spring-beans-and-dependency-injection

Related