我试图建立两个独立的项目:
myApplicationWorker 的 build.gradle 依赖关系如下所示:
dependencies {
compile('org.springframework.boot:spring-boot-starter')
compile project(':common')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
和 myApplicationCommon 的 build.gradle 依赖关系如下所示:
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('mysql:mysql-connector-java')
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.9.1'
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.9.1'
compile('org.apache.commons:commons-text:1.1')
testCompile("com.h2database:h2")
testCompile('junit:junit:5.0.2')
testCompile('org.mockito.mockito-core:2.12.0')
}
(包含测试/模拟/日志记录依赖项以及JPA / MySQL依赖项。)
简单的hibernate / datasource属性在 application.properties 中定义:
spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=url
spring.datasource.username=username
spring.datasource.password=password
我有一个" 帐户"模型定义:
package com.myapplication.common.models;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "accounts")
public class Account {
@Id
private long id;
//Other variables, getters/setters omitted for length
并且帐户模型具有 AccountRepository
package com.myapplication.common.models.repositories;
import com.myapplication.common.models.Account;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface AccountRepository extends CrudRepository<Account, Long> {
Account findAccountById(long id);
}
我的目标是让我的任何项目能够依赖公共项目与后端MySQL数据库进行交互,只需依赖于公共项目即可。我希望这可以在我的工作包中使用:
package com.myapplication.worker;
import com.myapplication.common.models.repositories.AccountRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@SpringBootApplication
@EnableJpaRepositories(basePackages = {"com.myapplication.common"})
@EntityScan(basePackages = {"com.myapplication.common"})
public class Application {
@Autowired
private AccountRepository accountRepository;
public static void main(String[] args) {
Application application = new Application();
application.testPrintAccountId();
}
public void testPrintAccountId() {
System.out.println(accountRepository.findAccountbyId(1).getAccountId());
}
}
当我尝试与testPrintAccountId()中的accountRepository交互时,这给了我一个NPE,但是,当我手动初始化上下文时,它(显然)有效:
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class);
AccountRepository accountRepository = context.getBean(AccountRepository .class);
System.out.println(accountRepository .findById(1234).getAccountId());
(Successfully returns result)
}
我明显误解了Spring和Spring Boot应该如何在这里工作。如何实现我的目标,即能够将我的共同项目中的存储库自动装配到其他项目中?
答案 0 :(得分:1)
如果要在主类中自动连接依赖项。 Spring还没有将依赖项自动装入App对象。如果要在Spring完成创建和自动装配后调用此方法,请添加带有@PostConstruct注释的方法来执行此操作,例如:
@SpringBootApplication
public class Application {
@Autowired
private AccountRepository accountRepository;
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@PostConstruct
public void testPrintAccountId() {
System.out.println(accountRepository.findAccountbyId(1).getAccountId());
}
}
或者您可以在@Component类中使用它,例如@Controller @Service
答案 1 :(得分:0)
万一有人像我一样来这里
这是可能的,因此OP可能还有其他NPE问题。在非核心模块/应用程序中,这对我有用:
@SpringBootApplication
@EnableJpaRepositories("com.package.domain.respositories")
@ComponentScan("com.package.domain")
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
测试运行正常,并且ClientApp从Domain包中加载存储库而没有问题。