web-dev-qa-db-ger.com

SpringBoot: Klasse kann nicht automatisch aus der anderen Jar-Bibliothek übernommen werden

Ich entwickle eine SpringBoot-Anwendung (z. B. MyApp) mit Abhängigkeit zu zwei Datenprojekten mit unterschiedlicher Implementierung:

data-jdbc.jar

  • erstellt mit dem spring-boot-starter-jdbc, der die JDBCDataService-Klasse verfügbar macht, die von meiner Anwendung verwendet wird

Beispielcode:

@Service 
public class JDBCDataServiceImpl implements JDBCDataService {

@Autowired
private JDBCDataRepository jdbcDataRepository;    
... 
}
  • mit Paket my.data.jdbc
  • es gibt keine SpringBoot-Hauptklasse. Federkonfiguration nur für die Komponententestklassen erstellt
  • die Repository-Klassen verwenden JDBCTemplate

Beispiel-Repository:

@Repository
public class JDBCDataRepositoryImpl implements JDBCDataRepository {

@Autowired
protected JdbcTemplate jdbcTemplate;
...
}

data-jpa.jar

  • mit spring-boot-starter-data-jpa erstellt, wodurch auch die Klasse JPADataService verfügbar gemacht wird, die auch von meiner Anwendung verwendet wird

Beispielcode:

@Service 
public class JPADataServiceImpl implements JPADataService {

@Autowired
private JPADataRepository jpaDataRepository;    
... 
}
  • mit Paket my.data.jpa
  • es gibt keine SpringBoot-Hauptklasse. Federkonfiguration nur für die Komponententestklassen erstellt
  • repository-Klassen erweitern die CrudRepository-Schnittstelle

Beispiel-Repository:

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

In meinem SpringBoot-Projekt habe ich die folgende SpringBoot-Hauptanwendung:

@SpringBootApplication
public class MyApp extends SpringBootServletInitializer {
}

In meiner Business-Service-Klasse MainService habe ich folgende Injektion 

@Service
public class MainServiceImpl implements MainService {

@Autowired
private JDBCDataService jdbcDataService;

@Autowired
private JPADataService jpaDataService;

Ich bin jedoch auf das Problem "Could not Autowire. No beans of 'JPADataService' type found" gestoßen, das nur für die Klasse JPADataService existiert, aber für die JDBCService-Klasse einwandfrei funktioniert.

Ich habe die in den folgenden Fragen gefundene Lösung ausprobiert, aber in meinem Fall funktioniert keine davon:

Kann ich nicht eine Bean @Autowire, die in einem abhängigen Library Jar vorhanden ist?

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

Wie kann ich eine Spring-Bohne @Autowire aus einem externen Glas erstellen?

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

Ich habe jetzt die Lösung für mein Problem gefunden. Ich muss meine Hauptversion von MyApp.Java um eine Paketstufe nach oben verschieben, um meine Datenbibliotheken zu scannen.

Anstatt mein MyApp.Java unter my.app zu packen, muss ich es unter my verschieben, um meine Bibliotheken erfolgreich mit my.data.jpa und my.data.jdbc-Paketen zu scannen.

14
Jown

Ich habe jetzt die Lösung für mein Problem gefunden. Ich muss meine Hauptversion von MyApp.Java um eine Paketstufe nach oben verschieben, um meine Datenbibliotheken zu scannen.

Anstatt mein MyApp.Java unter my.app zu packen, muss ich es unter my verschieben, um meine Bibliotheken erfolgreich mit my.data.jpa und my.data.jdbc-Paketen zu scannen.

6
Jown

Das Hinzufügen von @ComponentScan funktioniert nicht, wenn die Klasse, die Sie als Autowire versuchen, nicht mit @Component versehen wird. Damit dies funktioniert, müssen Sie eine Methode in Ihrer @Configuration-Klasse kommentieren. So etwas sollte es Ihnen ermöglichen, die Klasse automatisch abzuwickeln:

@Configuration
public class ConfigClass{

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

Sie müssen spring.factories am externen Jar konfigurieren:

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

der Kontext von spring.factories wie folgt:

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