0

I have a project structure similar to the one linked here: https://stackoverflow.com/a/29583882/1243462 . I have a util library containing a Service class in one JAR, meant to be consumed from another Java library/Maven project. However, my Service class itself uses Constructor Injection. So, where the original question had:

@Service
public class PermissionsService { ... }

I have

@Service
public class PermissionsService {

  public PermissionsService(@Autowired PermissionsDao dao) { 
   //assign private dao field to autowired dao
  }

}

And, like the original post, I want to create an instance of PermissionsService and inject it into my client/consumer application. I'm not sure of how to create a Configuration class.

 @Configuration
 public class PersistenceConfig {

   public PermissionsService getPermissionsServiceBean() {
     //What goes here?
   }
}

For now, I have a workaround where I replaced the @Autowired PermissionsDao constructor argument with a field injection, and having a no-args constructor. This allows me to:

 @Configuration
 public class PersistenceConfig {

   public PermissionsService getPermissionsServiceBean() {
     return new PermissionsService();
   }
}

But, since Field injection is discouraged, what is the right way to structure this code?

shikharraje
  • 127
  • 1
  • 17

1 Answers1

2

In your main module

@Configuration
@Import(PersistenceConfig.class)
public class ServiceConfig() {

}

In your utils module

@Configuration
@ComponentScan(basePackages = {"path-to-persistence-service-and-any-dependencies"})
public class PersistenceConfig {

}

The fact that you use constructor injection for PermissionsDao should not matter if you get the configuration right.

  • Hi, quick question. Does that mean that the main module `ServiceConfig` class needs to know beforehand that the required Import is `PersistenceConfig.class`? I was wondering if there was something like `@SpringBootApplication` that could just create a `PermissionsService` so that I don't need to know which Config class is needed. Off the top of my head, one issue could be if I'm using multiple Configs for differet Spring Profiles i.e. `PersistenceConfigX` (say, for Postgres) and `PersistenceConfigY` (MySQL), which would need `ServiceConfig` to know EXACTLY which PersistenceConfig to choose – shikharraje Oct 05 '18 at 11:45
  • Just in case, documentation on Spring Profiles: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-profiles.html – shikharraje Oct 05 '18 at 11:46
  • 1
    `@SpringBootApplication` does a `@ComponentScan` on the package where it's defined (in your example, that would be `com.yourorg.main`). Since `com.yourorg.utils` would not be a child under `com.yourorg.main`, the configuration from the utils module won't get picked up by default, so you would have to manually import it (via an `@Import` from somewhere within the scan path). –  Oct 05 '18 at 11:53
  • 1
    Regarding profiles, you should then no longer define the beans in the utils module, but in the `@Configuration` classes (a configuration for each profile, each defining their respective beans). –  Oct 05 '18 at 11:55
  • 1
    Or define profiled configurations in utils as well, that would be another way of doing it. –  Oct 05 '18 at 11:56