基于弹簧MVC注释的多模块项目配置

2022-09-04 04:53:44

我实现了两个基于maven的独立Web项目,使用Spring MVC,hibernate和Jax-RS实现。

但是我的要求改变了,现在我需要将这两个项目作为子项目合并到另一个项目中,即我们的父项目。所以我使用maven multimodule配置。

项目 1:父项目

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

儿童 1:

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

儿童 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>

但是我需要在Java中配置项目,以便它将扫描父项目和子项目的组件并执行项目。目前,我对每个项目都有单独的配置,如下所示:

应用集成器.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[] { "/" };
    }
}

应用配置.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/");
      
    }
}

休眠配置.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;
    }
}

答案 1

第二模块如果其弹簧Mvc或任何web应用程序模块,那么它应该具有第一模块的依赖性。在下面起草一个示例结构,希望这有帮助:

孩子1 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>

孩子2 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>

此外,您还可以根据应用程序配置中的休眠配置进行连接,例如:

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

答案 2

最好的配置是使用一个叫做Maven Reactor项目的东西。好的是,似乎你正在使用它。

首先,您的父级不应该有任何弹簧组件,它应该仅由POM(BOM - 物料清单)组成,以仅定义依赖项版本,并且可能要在子模块之间共享一些插件。这些依赖关系应该在依赖管理标记中,插件应该在插件管理中,但这实际上取决于您是否需要强制执行或不在子模块中强制执行某些行为。

如果您有父POM和两个子模块,并且您希望扫描两个子模块中的Spring组件,那么我个人会使用相同的父POM创建第三个子模块,并将两个子模块作为依赖项。在你的主类中,我会简单地用 custom 定义它,它有一个参数来定义要扫描的包。您可以使用两个模块的包前缀来填充该参数,并且很高兴。@SpringBootApplication@ComponentScan

另一种方法是创建完全独立的项目,这取决于这些子模块。但是,这要求您在本地 maven 存储库中安装这些子模块。在第一个解决方案中,如果始终一次生成整个项目,则不得在存储库中安装这些内容。


推荐