Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MVC annotation based Configuration for multimodule project

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.

Project 1: Parent project

<packaging>pom</packaging>
<modules>
    <module>../child1</module>
    <module>../child2</module>
</modules>

Child 1:

<packaging>jar</packaging>
<parent>
    <groupId>com.xyz.alpha</groupId>
    <artifactId>parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <relativePath>../parent</relativePath>
</parent>

Child 2:

<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:

AppIntializer.java

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[] { "/" };
    }
}

AppConfig.java

@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/");
      
    }
}

HibernateConfiguration.java

@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;
    }
}
like image 908
dhyanandra singh Avatar asked Feb 14 '26 16:02

dhyanandra singh


1 Answers

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.

like image 111
Adam Ostrožlík Avatar answered Feb 17 '26 06:02

Adam Ostrožlík



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!