部署使用Maven的Spring Boot项目,并在其他项目中进一步导入

huangapple go评论77阅读模式
英文:

Deploying a Spring-Boot project using Maven and further importing it in other projects

问题

目前,我有两个项目,我们称为 Storefront 和 Dashboard,这两个项目都有相同的 POJO 类、服务和一些 API 端点。例如,考虑一个名为 Student 的类,在 Storefront 和 Dashboard 中都有这个类,以及它的服务类。此外,在不久的将来,我们将为客户实施另一个项目,即客户 Dashboard,它将拥有几乎 90% 相同的资源。

于是我想,如果我创建一个 Maven 项目,将所有项目需要的库都放在里面,按需进行导入。这将减少冗余,并使其他项目变得更加轻量。我之前使用过项目内仓库和 Dropbox 作为 Maven 仓库,所以这次对我来说会比较容易。

现在的问题是:我有一个与 Student 对应的 StudentRepository,它会使用 @Autowired 注解,对吗?据我所知,当我运行 @SpringBootApplication 时,一切都会正常工作,但正如我之前提到的,我将会导入这些包,这样做的话,程序会抛出空指针异常,因为 StudentRepository 的实例将为 null。

@SpringBootApplication
@EnableAutoConfiguration
@EntityScan
public class DemoApplication implements CommandLineRunner {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	StudentRepository repository;

	public static void main(String[] args) {
		SpringApplication.run(PaperTrueLibrariesApplication.class, args);
	}

	@Override
	public void run(String... args) throws Exception {
		// This will work
		logger.info("Inserting -> {}", repository.save(new Student("studentName", "primaryKey")));
	}
	
	// This won't
	public void addAStudent(String studentName, String primaryKey) {
		repository.save(new Student(studentName, primaryKey));
	}

}
public class Test {

	public static void main(String[] args) {
		// This will throw a NullPointerException
		new DemoApplication().addAStudent("yourNameProbably", "yourSocialSecurityNumber");
	}

}

那么,有没有其他方法使这个工作起来?欢迎提出任何建议,提前谢谢。

英文:

So currently, I have two projects, let's say Storefront and Dashboard, and both of these projects have the same POJO classes, Services, and some API Endpoints. For example, consider a class Student, we have this class in Storefront as well as in the Dashboard along with its service class. Further, in near future, we'll be implementing another project for clients, a Client Dashboard, that'll have almost 90% of the same resources.

So I thought, what if I create a maven project with all the libraries I need across all projects and import them as needed. This would reduce the redundancy and would also make other projects light weighted. I've previously used the in-project repository and Dropbox as a maven repository so it'll be a bit easier for me this time.

Now the problem is: I have the StudentRepository corresponding to the Student, which is further used with the '@Autowired' annotation right? As per my knowledge, everything will work when I run the '@SpringBootApplication' but as I previously mentioned, I'll be importing these packages, and doing so, the program will through a NullPointerException cause the instance of the StudentRepository will be null.

@SpringBootApplication
@EnableAutoConfiguration
@EntityScan
public class DemoApplication implements CommandLineRunner {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	StudentRepository repository;

	public static void main(String[] args) {
		SpringApplication.run(PaperTrueLibrariesApplication.class, args);
	}

	@Override
	public void run(String... args) throws Exception {
		// This will work
		logger.info("Inserting -> {}", repository.save(new Student("studentName", "primaryKey")));
	}
	
	// This won't
	public void addAStudent(String studentName, String primaryKey) {
		repository.save(new Student(studentName, primaryKey));
	}

}
public class Test {

	public static void main(String[] args) {
		// This will throw a NullPointerException
		new DemoApplication().addAStudent("yourNameProbably", "yourSocialSecurityNumber");
	}

}

So is there any other way to make this work? Any suggestions will be appreciated and thanks in advance.

答案1

得分: 1

有两种方法可以实现你想要的 -

首先,将你已经在构建文件(比如maven的pom.xml)中创建的必需jar包添加到你当前的项目中。

如果你在不同的项目中导入的类或代码不是一个Spring Bean,那么

在你的配置类中,将其以bean的形式返回,使用@Bean注解。

@Configuration
public class YourConfigurationClass {    

    @Bean
    SomeBean returnSomeBean() {
        return new SomeBean();
    }
}

如果你的类已经是一个Spring Bean,你只需要让Spring扫描所需的包,因为你已经通过在Maven中添加依赖项将其添加到了类路径中。

@Configuration
@ComponentScan({"com.yourpackage.fromCommanCodeJar"})
public class YouApplicationConfigurationClass {...}
英文:

There are two ways to achieve what you want -

First of all, add required jar that you have already created in your build file, say pom.xml for maven, in your current project.

If the class or code you are importing in different project is not a spring bean, then

In your configuration class, return it as a bean, using @Bean annotaion.

@Configuration
public class YourConfigurationClass {    

@Bean
SomeBean returnSomeBean() {
    return new SomeBean();
}

If your class is already a spring bean, you just need to ask spring to scan required package, as you already have that in your class path by adding dependency in maven.

@Configuration
@ComponentScan({"com.yourpackage.fromCommanCodeJar"})
public class YouApplicationConfigurationClass {....}

答案2

得分: 1

假设您有一个库 FooLibrary 和主应用程序 FooApplication。其思想是在 FooApplication 中导入 FooLibrary

让我们从 FooLibrary 开始。主要有两个重要文件。这些是 FooLibraryInterfaceFooLibraryConfiguration。在这个示例中,我将不使用 FooLibraryInterface

FooLibraryInterface 是一个包含客户端可能需要 override 的重要方法的接口,而 FooLibraryConfiguration 则用于扫描并注入在 FooLibrary 中找到的 bean。因此,它如下所示:

public interface FooLibraryInterface {
    public abstract Datasource configureDatabaseConnection();
}

FooLibraryConfiguration 将如下所示:

@Configuration
@ComponentScan("package.to.scan")
public class FooLibraryConfiguration {
    @Bean
    public YourBean beanName() {
        return new YourBean();
    }
}

您可以在 FooLibrary 中添加所有您需要的内容。现在我们的库已经准备好可以在 FooApplication 中导入,借助于 FooLibraryConfiguration

@SpringBootApplication
@Import(FooLibraryConfiguration.class) //this will import all the beans defined in the library
public class FooApplication {
    public static void main(String[] args) {
        SpringApplication.run(FooApplication.class, args);
    }
}

注意:如果您有 EntityManager 管理的类(实体、存储库),则应在主应用程序中进行额外的库包扫描,因为我们不需要为单个应用程序使用不同的 EntityManager。或者您可以一起扫描所有文件(从 @EnableJpaRepositoriesem.setPackagesToScan("library.entities.package");@ComponentScan("base.library.package") 的单独扫描)

@Configuration
@EnableJpaRepositories(basePackages = { "library.repository.package" })
@EnableTransactionManagement
public class PersistenceConfig {
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        em.setPackagesToScan("library.entities.package");

        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        em.setJpaProperties(additionalProperties());

        return em;
    }
    .....
}

更新

感谢 @keshavram-kuduwa,您可以从 https://spring.io/guides/gs/multi-module/#_create_the_library_project 访问 Spring 指南。

英文:

Assume that you have a library FooLibrary and main application FooApplication. The idea is importing FooLibrary in FooApplication.

Let's begin with FooLibrary. So mainly there are 2 important files. These are FooLibraryInterface and FooLibraryConfiguration. In this example I will not use FooLibraryInterface.

FooLibraryInterface is an interface that holds important methods that the client might need to override and FooLibraryConfiguration to scan and inject beans found in FooLibrary. So, here it follows

public interface FooLibraryInterface {
	public abstract Datasource configureDatabaseConnection();
}

FooLibraryConfiguration will be as the following:

@Configuration
@ComponentScan("package.to.scan")
public class FooLibraryConfiguration {
	@Bean
	public YourBean beanName() {
		return new YourBean();
	}
}

You can add all that you need in FooLibrary. Now our library is ready to be imported in FooApplication with the help of FooLibraryConfiguration

@SpringBootApplication
@Import(FooLibraryConfiguration.class) //this will import all the beans defined in the library
public class FooApplication {
	public static void main(String[] args) {
		SpringApplication.run(FooApplication.class, args);
	}
}

NOTE: If you have EntityManager managed classes(entity, repository), you should do an additional scan of the lib packages in the main application, since we don't need to have different EntityManager for a single application. Or you may scan all files together (leaving individual scans from @EnableJpaRepositories or em.setPackagesToScan("library.entities.package"); with @ComponentScan("base.library.package"))

@Configuration
@EnableJpaRepositories(basePackages = { "library.repository.package" })
@EnableTransactionManagement
public class PersistenceConfig {
	@Bean
	public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
		LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
		em.setDataSource(dataSource());
		em.setPackagesToScan("library.entities.package");

		JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
		em.setJpaVendorAdapter(vendorAdapter);
		em.setJpaProperties(additionalProperties());

		return em;
	}
	.....
}

UPDATE

Thank you @keshavram-kuduwa, you can reach the spring guides from https://spring.io/guides/gs/multi-module/#_create_the_library_project

huangapple
  • 本文由 发表于 2020年10月27日 20:28:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/64554436.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定