Is there a way to integrate spring-batch-admin and spring-boot properly?

后端 未结 5 1415
抹茶落季
抹茶落季 2021-01-04 12:34

According to the documentation spring batch admin is very easy to embed into the existing application. Simply copying web.xml and index.jsp then adding needed dependencies i

相关标签:
5条回答
  • 2021-01-04 12:50

    The short answer is that you won't want to use @EnableBatchProcessing with Spring Batch Admin. SBA provides a number of beans on a global scale that the @EnableBatchProcessing also provides. SBA 2.0 (currently in development) will probably fill the gaps between what is currently there and what @EnableBatchProcessing provides (specifically providing the JobBuilderFactory and StepBuilderFactory).

    To get yourself running, you should be able to (I haven't tired this myself) configure in the META-INF/spring/batch/override/ directory a JobBuilderFactory and a StepBuilderFactory for global use. From there, you can use XML files in the META-INF/spring/batch/jobs directory that do nothing more than component scan for your @Configuration classes. However, leave off the @EnableBatchProcessing because of the duplication of beans.

    For the record, this isn't an Spring Boot issue since @EnableBatchProcessing is a Spring Batch annotation, not a Boot one.

    0 讨论(0)
  • 2021-01-04 12:50

    Spring Batch Admin 2.0-BUILD-SNAPSHOT introduce a new Annoation @EnableBatchAdmin for easy to integrate with spring boot. There is also a samples project https://github.com/spring-projects/spring-batch-admin-samples.

    0 讨论(0)
  • 2021-01-04 12:56

    to complete the answer, here is the code to create the two beans once you disable the @EnableBatchProcessing annotation

    @Autowired
    JobRepository jobRepository;
    @Autowired
    PlatformTransactionManager transactionManager;
    
    @Bean
    public JobBuilderFactory jobBuilderFactory() {
        return new JobBuilderFactory(jobRepository);
    }
    
    @Bean
    public StepBuilderFactory stepBuilderFactory() {
        return new StepBuilderFactory(jobRepository, transactionManager);
    }
    
    0 讨论(0)
  • 2021-01-04 13:04

    This ClassCastException is caused by

    classpath:/org/springframework/batch/admin/web/resources/servlet-config.xml

    loading

    META-INF/spring/batch/servlet/resources/resource-context.xml

    which contains

    <mvc:annotation-driven />

    This conflicts with the mvc configuration in the Spring Java configuration class. The following class can be used to embed Spring Batch Admin within an existing application that uses Java configuration.

    @Configuration
    @EnableWebMvc
    @ImportResource({"classpath*:/META-INF/spring/batch/bootstrap/**/*.xml"
        , "classpath*:/META-INF/spring/batch/override/**/*.xml"
        , "classpath*:/org/springframework/batch/admin/web/resources/webapp-config.xml" 
        , "classpath*:/META-INF/spring/batch/servlet/manager/**/*.xml"
        , "classpath:base-menu-config.xml"
        })
    public class SpringBatchAdminConfig extends WebMvcConfigurerAdapter {
    
        @Override
        public void addResourceHandlers(final ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/resources/**").addResourceLocations("classpath:/META-INF/");      
        }
    
        @Bean
        public SimpleControllerHandlerAdapter simpleControllerHandlerAdapter() {
            return new SimpleControllerHandlerAdapter();
        }
    
        @Bean
        public BeanNameUrlHandlerMapping beanNameUrlHandlerMapping() {
            return new BeanNameUrlHandlerMapping();
        }
    
        @Bean
        public BeanNameViewResolver beanNameViewResolver() {
            return new BeanNameViewResolver();
        }
    
        @Bean(name = "defaultResources")
        public PropertiesFactoryBean defaultResources() {
            return new PropertiesFactoryBean();
        }
    
        @Bean(name = "jsonResources")
        public PropertiesFactoryBean jsonResources() {
            return new PropertiesFactoryBean();
        }
    
        @Bean
        public HomeController homeController() throws IOException {
            HomeController homeController = new HomeController();
            homeController.setDefaultResources(defaultResources().getObject());
            homeController.setJsonResources(jsonResources().getObject());
            return homeController;
        }
    
        @Bean
        public MenuManager menuManager() {
            return new MenuManager();
        }
    
        @Bean(name = "freemarkerConfig")
        public HippyFreeMarkerConfigurer hippyFreeMarkerConfigurer() {
            HippyFreeMarkerConfigurer hippyFreeMarkerConfigurer = new HippyFreeMarkerConfigurer();
            hippyFreeMarkerConfigurer.setTemplateLoaderPaths("/WEB-INF/web", "classpath:/org/springframework/batch/admin/web");
            hippyFreeMarkerConfigurer.setPreferFileSystemAccess(false);
            hippyFreeMarkerConfigurer.setFreemarkerVariables(Collections.singletonMap("menuManager", (Object) menuManager()));
            Properties freemarkerSettings = new Properties();
            freemarkerSettings.put("default_encoding", "UTF-8");
            freemarkerSettings.put("output_encoding", "UTF-8");
            hippyFreeMarkerConfigurer.setFreemarkerSettings(freemarkerSettings);
            return hippyFreeMarkerConfigurer;
        }
    
        public AjaxFreeMarkerView parentLayout() {
            AjaxFreeMarkerView ajaxFreeMarkerView = new AjaxFreeMarkerView();
            FreeMarkerViewResolver freeMarkerViewResolver = new FreeMarkerViewResolver();
            freeMarkerViewResolver.setExposeSpringMacroHelpers(false);
            freeMarkerViewResolver.setAllowRequestOverride(true);
            ajaxFreeMarkerView.setViewResolver(freeMarkerViewResolver);
            Properties attributes = new Properties();
            attributes.put("titleCode", "home.title");
            attributes.put("titleText", "Spring Batch Admin");
            ajaxFreeMarkerView.setAttributes(attributes);
            return ajaxFreeMarkerView;
        }
    
        @Value("#{resourceService.servletPath}")
        private String servletPath;
    
        @Bean(name="standard")
        public AjaxFreeMarkerView standard() {
            AjaxFreeMarkerView standard = parentLayout();
            standard.setUrl("/layouts/html/standard.ftl");
            standard.setContentType("text/html;charset=UTF-8");
            standard.getAttributesMap().put("body", "/layouts/html/home.ftl");
            standard.getAttributesMap().put("servletPath", servletPath);
            return standard;        
        }
    
        @Bean(name="standard.rss")
        public AjaxFreeMarkerView standardRss() {
            AjaxFreeMarkerView standardRss = parentLayout();
            standardRss.setUrl("/layouts/html/standard.ftl");
            standardRss.setContentType("text/xml");
            standardRss.getAttributesMap().put("body", "/layouts/rss/home.ftl");
            standardRss.getAttributesMap().put("servletPath", servletPath);
            return standardRss;     
        }
    
        @Bean(name="standard.json")
        public AjaxFreeMarkerView standardJson() {
            AjaxFreeMarkerView standardJson = parentLayout();
            standardJson.setUrl("/layouts/json/standard.ftl");
            standardJson.setContentType("application/json");
            standardJson.getAttributesMap().put("body", "/layouts/json/home.ftl");
            standardJson.getAttributesMap().put("servletPath", servletPath);
            return standardJson;        
        }
    
        @Bean(name="home")
        public AjaxFreeMarkerView home() {
            return standard();
        }
    
        @Bean(name="home.json")
        public AjaxFreeMarkerView homeJson() {
            AjaxFreeMarkerView homeJson = standardJson();
            homeJson.getAttributesMap().put("body", "/layouts/json/home.ftl");
            return homeJson;
        }
    
    
    }
    

    A single XML file is also required for the abstract base menu which is referenced elsewhere in the Spring Batch Admin project. This is required as abstract beans can not be provided from a Spring Java configuration.

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    
        <bean id="baseMenu" abstract="true">
            <property name="prefix" value="#{resourceService.servletPath}" />
        </bean>
    
    </beans>
    

    Maven dependencies. Take care to ensure only a single version of the base Spring framework is pulled in by Maven.

    <dependency>
        <groupId>org.springframework.batch</groupId>
        <artifactId>spring-batch-admin-manager</artifactId>
        <version>1.3.1.RELEASE</version>
    </dependency>
    <dependency>
            <groupId>hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <scope>runtime</scope>
            <version>1.8.0.10</version>
    </dependency>
    

    Spring batch also expects in a default configuration for the following files to exist at the root of the classpath.

    batch-default.properties

    # Default placeholders for database platform independent features 
    batch.remote.base.url=http://localhost:8080/spring-batch-admin-sample
    # Non-platform dependent settings that you might like to change
    batch.job.configuration.file.dir=/tmp/config
    
    build.artifactId=1
    build.version=1
    build.buildNumber=1
    build.timestamp=1
    log.enableConsole=true
    

    batch-hsql.properties

    # Placeholders batch.*
    #    for HSQLDB:
    batch.jdbc.driver=org.hsqldb.jdbcDriver
    batch.jdbc.url=jdbc:hsqldb:mem:testdb;sql.enforce_strict_size=true
    # Override and use this one in for a separate server process so you can inspect 
    # the results (or add it to system properties with -D to override at run time).
    # batch.jdbc.url=jdbc:hsqldb:hsql://localhost:9005/samples
    batch.jdbc.user=sa
    batch.jdbc.password=
    batch.database.incrementer.class=org.springframework.jdbc.support.incrementer.HsqlMaxValueIncrementer
    batch.schema.script=classpath*:/org/springframework/batch/core/schema-hsqldb.sql
    batch.drop.script=classpath*:/org/springframework/batch/core/schema-drop-hsqldb.sql
    batch.business.schema.script=classpath:/business-schema-hsqldb.sql
    
    # Non-platform dependent settings that you might like to change
    # batch.data.source.init=true
    

    business-schedule-hsqldb.sql

    DROP TABLE  ERROR_LOG IF EXISTS;
    CREATE TABLE ERROR_LOG  (
            JOB_NAME CHAR(20) ,
            STEP_NAME CHAR(20) ,
            MESSAGE VARCHAR(300) NOT NULL
    ) ;
    
    0 讨论(0)
  • 2021-01-04 13:08

    I've a working version here based on the same example (I forked the original one): https://github.com/vesperaba/spring-batch-admin-spring-boot.

    I followed Michael Minella advice and I overwrote the SpringBatch property holder with a custom one.

    I also added a job to check it's working now

    0 讨论(0)
提交回复
热议问题