模块拆分弹簧配置

时间:2018-04-08 19:29:31

标签: java spring spring-mvc configuration

我试图将可行的spring应用程序拆分为逻辑上分离的模块。让我们简化条件并想象我们只有一个模块BusinessAppConf(这个仅用于用户WEB交互目的)和主应用程序上下文初始化器。

这是一个可行的方案,但使用静态方法来注册与业务模块相关的配置类。

WebApplicationInitializer(web.xml被此接口的实现取代)

public class AppInitializer implements WebApplicationInitializer {

    @Override
    @Autowired
    public void onStartup(ServletContext container) throws ServletException {
        AnnotationConfigWebApplicationContext context = getContext();
        container.addListener(new ContextLoaderListener(context));

        ServletRegistration.Dynamic mainDispatcher =
                container.addServlet("dispatcher", new DispatcherServlet(context));
        ServletRegistration.Dynamic businessDispatcher =
                container.addServlet("businessDispatcher", BusinessAppConfig.createDispatcherServlet(context));
        ServletRegistration.Dynamic ppaDispatcher =
                container.addServlet("ppaDispatcher", PpaAppConfig.createDispatcherServlet(context));

        initDispatcher(mainDispatcher, 1, "/");
        initDispatcher(businessDispatcher, 2, "/business");
        initDispatcher(businessDispatcher, 3, "/ppa");
    }

    private void initDispatcher(ServletRegistration.Dynamic dispatcher, int loadOnStartUp, String mapping) {
        if (dispatcher == null) {
            System.out.println("Servlet" + dispatcher.getName() + " is already added");
        } else {
            dispatcher.setLoadOnStartup(loadOnStartUp);
            dispatcher.addMapping(mapping);
        }
    }

    public AnnotationConfigWebApplicationContext getContext() {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(MvcConfiguration.class);
        return context;
    }

    @Bean(name = "propertyConfigurer")
    public PropertySourcesPlaceholderConfigurer getPropertyPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer placeholderConfigurer = new PropertySourcesPlaceholderConfigurer();
        placeholderConfigurer.setLocation(new ClassPathResource("common.properties"));
        placeholderConfigurer.setLocation(new ClassPathResource("amazon.S3Storage.properties"));
        placeholderConfigurer.setLocation(new ClassPathResource("local.storage.properties"));
        placeholderConfigurer.setLocation(new ClassPathResource("log4j.properties"));
        placeholderConfigurer.setIgnoreUnresolvablePlaceholders(true);
        return placeholderConfigurer;
    }
}

使用静态方法的Business Config模块:

BusinessAppConfig类文件

@Configuration
public class BusinessAppConfig {

    public static Servlet createDispatcherServlet(AnnotationConfigWebApplicationContext context) {
        context.register(BusinessMvcConfig.class);
        return new DispatcherServlet(context);
    }
}

BusinessMvcConfig class config

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ComponentScan(basePackages = {"business"})
@EnableWebMvc
public class BusinessMvcConfig extends WebMvcConfigurationSupport {

    @Bean
    public ViewResolver getViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setViewClass(JstlView.class);
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

    @Bean(name = "multipartResolver")
    public CommonsMultipartResolver multipartResolver() {
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
        multipartResolver.setMaxUploadSize(500000000L);
        return multipartResolver;
    }
}

BusinessHibernateConfig.class

@Configuration
@EnableTransactionManagement
//@EnableJpaRepositories(basePackages = {"business.dao", "business.model", "ppa.dao", "ppa.model"})
@PropertySource("classpath:rdbmsDev.properties")
public class BusinessHibernateConfig {

@Autowired
private Environment env;

@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws NamingException, IOException {
    LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();

    Properties createStrategy = new Properties();
    createStrategy.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));

    emf.setJpaProperties(createStrategy);
    emf.setPackagesToScan("business");
    emf.setJpaVendorAdapter(getJpaVendorAdapter());
    BasicDataSource dataSource = getDataSource();
    emf.setDataSource(dataSource);

    return emf;
}

@Bean
public DatabasePopulator createDatabasePopulator(BasicDataSource dataSource) {
    ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
    databasePopulator.setContinueOnError(false);
    databasePopulator.addScript(new ClassPathResource("create.sql"));
    DatabasePopulatorUtils.execute(databasePopulator, dataSource);
    return databasePopulator;
}

private JpaVendorAdapter getJpaVendorAdapter() {
    HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
    jpaVendorAdapter.setShowSql(true);
    jpaVendorAdapter.setGenerateDdl(false);
    jpaVendorAdapter.setDatabasePlatform(env.getProperty("hibernate.dialect"));
    return jpaVendorAdapter;
}

@Bean
public BasicDataSource getDataSource() {
    BasicDataSource basicDataSource = new BasicDataSource();
    basicDataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
    basicDataSource.setUsername(env.getProperty("jdbc.username"));
    basicDataSource.setPassword(env.getProperty("jdbc.password"));
    basicDataSource.setUrl(env.getProperty("jdbc.url"));
    basicDataSource.setInitialSize(Ints.tryParse(env.getProperty("connection.init_size")));
    basicDataSource.setMaxIdle(Ints.tryParse(env.getProperty("connection.pool_size")));
    return basicDataSource;
}

@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
    return new JpaTransactionManager(entityManagerFactory);
}

}

我不喜欢这里使用静态方法。这似乎是错误的实现。那么,接下来的问题是这些文件是否已正确配置?如果不应该如何配置?

1 个答案:

答案 0 :(得分:0)

使用AbstractContextLoaderInitializer代替WebApplicationInitializer,因为

  • 它为您注册ContextLoaderListener
  • 您可以使用您的代码注册调度程序servlet o onStartu方法
  • 您可以覆盖createRootApplicationContext方法来创建您的根应用程序包含业务服务的上下文,它将在ContextLoaderListener
  • 的情况下提供给BusinessAppConfig