SpringBoot: не может Autowire Class из другой библиотеки Jar

Я разрабатываю приложение SpringBoot (например, MyApp) с зависимостью от двух проектов данных с различной реализацией:

данных jdbc.jar

  • построенный с помощью spring-boot-starter-jdbc, который предоставляет класс JDBCDataService, который будет использоваться моим приложением

Пример кода:

@Service 
public class JDBCDataServiceImpl implements JDBCDataService {

@Autowired
private JDBCDataRepository jdbcDataRepository;    
... 
}
  • с пакетом my.data.jdbc
  • нет основного класса SpringBoot. Spring конфигурация, созданная только для классов unit test
  • классы репозитория используют JDBCTemplate

Пример репозитория:

@Repository
public class JDBCDataRepositoryImpl implements JDBCDataRepository {

@Autowired
protected JdbcTemplate jdbcTemplate;
...
}

данных jpa.jar

  • построенный с помощью spring-boot-starter-data-jpa, который также предоставляет класс JPADataService, который также будет использоваться моим приложением

Пример кода:

@Service 
public class JPADataServiceImpl implements JPADataService {

@Autowired
private JPADataRepository jpaDataRepository;    
... 
}
  • с пакетом my.data.jpa
  • нет основного класса SpringBoot. Spring конфигурация, созданная только для классов unit test
  • классы репозитория расширяют интерфейс CrudRepository

Пример репозитория:

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

В моем проекте SpringBoot у меня есть следующее приложение SpringBoot:

@SpringBootApplication
public class MyApp extends SpringBootServletInitializer {
}

В моем бизнес-классе MainService у меня есть следующая инъекция

@Service
public class MainServiceImpl implements MainService {

@Autowired
private JDBCDataService jdbcDataService;

@Autowired
private JPADataService jpaDataService;

Однако я столкнулся с проблемой "Could not Autowire. No beans of 'JPADataService' type found", которая существует только для класса JPADataService, но отлично работает для класса JDBCService.

Я пробовал решение, найденное в следующих вопросах, но ни один из них не работает в моем случае:

Разве я не могу @Autowire Bean, который присутствует в зависимой библиотеке Jar?

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

Как я могу @Autowire Spring Bean, который был создан из внешнего баннера?

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

Теперь я нашел решение по моей проблеме. Мне нужно переместить мой основной уровень MyApp.java на один уровень выше, чтобы сканировать мои библиотеки данных.

Вместо того, чтобы поместить мой MyApp.java в пакет my.app, я должен переместить его под my, чтобы успешно сканировать мои библиотеки с пакетами my.data.jpa и my.data.jdbc.

Ответ 1

Теперь я нашел решение по моей проблеме. Мне нужно переместить мой основной уровень MyApp.java на один уровень выше, чтобы сканировать мои библиотеки данных.

Вместо того, чтобы поместить мой MyApp.java в пакет my.app, я должен переместить его под my, чтобы успешно сканировать мои библиотеки с пакетами my.data.jpa и my.data.jdbc.

Ответ 2

Добавление @ComponentScan не будет работать, если класс, который вы пытаетесь Autowire, не аннотируется с @Component. Чтобы это сработало, вам нужно будет аннотировать метод в классе @Configuration. Что-то вроде этого должно позволить вам autwire класс:

@Configuration
public class ConfigClass{

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

Ответ 3

Вам необходимо spring.factories на внешнем банке:

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

контекст весны. Факторы, как это:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=xxx