Reputation: 1141
I implemented two maven based independent web project implemented using Spring MVC, hibernate and Jax-RS.
But my requirement changed and now I need to combine both the project as a sub project into another project which is our parent project. So I use maven multimodule configuration.
<packaging>pom</packaging>
<modules>
<module>../child1</module>
<module>../child2</module>
</modules>
<packaging>jar</packaging>
<parent>
<groupId>com.xyz.alpha</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent</relativePath>
</parent>
<packaging>jar</packaging>
<dependency>
<groupId>com.xyz.alpha</groupId>
<artifactId>child1</artifactId>
<version>2.0.2</version>
</dependency>
<parent>
<groupId>com.xyz.alpha</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent</relativePath>
</parent>
But I need to configure project in Java in such a way that it will scan components of the parent and both the child project and execute project. Currently I have separate configuration for each project as:
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { AppConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.x.y")
public class AppConfig extends WebMvcConfigurerAdapter{
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
@Configuration
@EnableTransactionManagement
@ComponentScan({ "com.x.y.configuration" })
@PropertySource(value = { "classpath:application.properties" })
public class HibernateConfiguration {
@Autowired
private Environment environment;
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[] { "com.x.y.model" });
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
return dataSource;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
return properties;
}
@Bean
@Autowired
public HibernateTransactionManager transactionManager(SessionFactory s) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(s);
return txManager;
}
}
Upvotes: 14
Views: 2271
Reputation: 1416
The best configuration for this is to use something called Maven Reactor project. Good is that it seems you are using it.
Firstly, your parent should not have any spring component, it should by composed of POM only (BOM - bill of materials) to define only dependency versions and maybe some plugins to be shared accross submodules. These dependencies should by in DependencyManagement tag and plugins should be in PluginManagement but it really depends on your need to enforce or not some behaviour in submodules.
If you have parent POM and two submodules and you want scan both submodules for Spring components then I would personally create third submodule with the same parent POM and both submodules as dependencies. In your main class, I would simply define @SpringBootApplication
with custom @ComponentScan
which has an argument defining packages to scan. You can fill that argument with package prefixes of both modules and you are good to go.
Other way is to create totally independent project which depends on those submodules. This demands however that you have those submodules installed in your local maven repository. In the first solution, you must not have these installed in your repo if you always build entire project at once.
Upvotes: 1
Reputation: 119
The second module if its spring Mvc or any webapplication module, then it should have a dependency of first module. Drafting an sample structure below, Hope this helps:
child1 pom:
<parent>
<groupId>com.xyz.alpha</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>child1-app</artifactId>
<packaging>jar</packaging>
<build>
</build>
<dependencies>
</dependencies>
child2 pom:
<parent>
<groupId>com.xyz.alpha</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>child2-Webapp</artifactId>
<packaging>war</packaging>
<build>
</build>
<dependencies>
<dependency>
<groupId>org.sonatype.mavenbook.multi</groupId>
<artifactId>child1-app</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
Also, you can wire up depending Hibernate configuration in the app configuration like:
@Import({HibernateConfiguration.class})
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.x.y")
public class AppConfig extends WebMvcConfigurerAdapter{
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
Upvotes: 0