web-dev-qa-db-fra.com

SpringBoot: impossible de classer Autowire par une autre bibliothèque de fichiers Jar

Je développe une application SpringBoot (par exemple, MyApp) avec dépendance à deux projets de données avec une implémentation différente:

data-jdbc.jar

  • construit en utilisant le spring-boot-starter-jdbc qui expose la classe JDBCDataService qui sera utilisée par mon application

Exemple de code:

@Service 
public class JDBCDataServiceImpl implements JDBCDataService {

@Autowired
private JDBCDataRepository jdbcDataRepository;    
... 
}
  • avec package my.data.jdbc
  • il n'y a pas de classe principale SpringBoot. Configuration de printemps créée uniquement pour les classes de test d'unité
  • les classes du référentiel utilisent JDBCTemplate

Exemple de référentiel:

@Repository
public class JDBCDataRepositoryImpl implements JDBCDataRepository {

@Autowired
protected JdbcTemplate jdbcTemplate;
...
}

data-jpa.jar

  • construit en utilisant le spring-boot-starter-data-jpa qui expose également la classe JPADataService qui sera également utilisée par mon application

Exemple de code:

@Service 
public class JPADataServiceImpl implements JPADataService {

@Autowired
private JPADataRepository jpaDataRepository;    
... 
}
  • avec package my.data.jpa
  • il n'y a pas de classe principale SpringBoot. Configuration de printemps créée uniquement pour les classes de test d'unité
  • classes de référentiel étend l'interface CrudRepository

Exemple de référentiel:

@Repository
public interface JPADataRepository extends CrudRepository<MyObject, Integer{
...
}

Dans mon projet SpringBoot, j'ai l'application principale SpringBoot suivante:

@SpringBootApplication
public class MyApp extends SpringBootServletInitializer {
}

Dans ma classe de services professionnels MainService, j'ai l'injection suivante 

@Service
public class MainServiceImpl implements MainService {

@Autowired
private JDBCDataService jdbcDataService;

@Autowired
private JPADataService jpaDataService;

Cependant, j'ai rencontré le problème "Could not Autowire. No beans of 'JPADataService' type found" qui n'existe que pour la classe JPADataService mais qui fonctionne correctement pour la classe JDBCService.

J'ai essayé la solution trouvée dans les questions suivantes, mais aucune de ces solutions ne fonctionne dans mon cas:

Je ne peux pas @Autowire un haricot présent dans un bocal de bibliothèque dépendant?

@ComponentScan(basePackages = {"org.example.main", "package.of.user.class"})

Comment puis-je @ Autowire un haricot de printemps qui a été créé à partir d'un pot externe?

@Configuration
@ComponentScan("com.package.where.my.class.is")
class Config {
...
}

J'ai maintenant trouvé la solution à mon problème. Je dois monter mon paquet principal MyApp.Java d'un niveau supérieur pour analyser mes bibliothèques de données.

Au lieu de placer mon package MyApp.Java sous le package my.app, je dois le déplacer sous my pour pouvoir analyser correctement mes bibliothèques avec les packages my.data.jpa et my.data.jdbc.

14
Jown

J'ai maintenant trouvé la solution à mon problème. Je dois monter mon paquet principal MyApp.Java d'un niveau supérieur pour analyser mes bibliothèques de données.

Au lieu de placer mon package MyApp.Java sous le package my.app, je dois le déplacer sous my pour pouvoir analyser correctement mes bibliothèques avec les packages my.data.jpa et my.data.jdbc.

6
Jown

L'ajout de @ComponentScan ne fonctionnera pas si la classe que vous essayez d'utiliser Autowire n'est pas annotée avec @Component. Pour que cela fonctionne, vous devez annoter une méthode dans votre classe @Configuration. Quelque chose comme ceci devrait vous permettre d'autowire la classe:

@Configuration
public class ConfigClass{

    @Bean
    public JPADataService jpaDataService(){
        return new JPADataService();
    }
}
6

Vous devez configurer spring.factories dans le fichier JAR externe:

external-jar-project
   |--Java
   |--resources
        |-- META-INF
              |-- spring.factories

le contexte de spring.factories, comme ceci:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=xxx
1
Bond Zhou