2015-06-01 2 views
0

Я немного смущен поведением весенней загрузки при перезаписи конкретных автоконфигураций.Завершение автоконфигурации пружинной загрузки

Мне нравится частично перезаписывать BatchAutoConfiguration, но, я думаю, мой вопрос не относится к BatchAutoConfiguration. На самом деле, я просто хочу «перезаписать» два метода этого класса: public BatchDatabaseInitializer batchDatabaseInitializer() и public ExitCodeGenerator jobExecutionExitCodeGenerator().

Поэтому я написал следующий код: package ch.test.autoconfig.autoconfigure;

import org.springframework.batch.core.launch.JobLauncher; 
import org.springframework.boot.ExitCodeGenerator; 
import org.springframework.boot.autoconfigure.AutoConfigureAfter; 
import org.springframework.boot.autoconfigure.AutoConfigureBefore; 
import org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration; 
import org.springframework.boot.autoconfigure.batch.BatchDatabaseInitializer; 
import org.springframework.boot.autoconfigure.batch.BatchProperties; 
import org.springframework.boot.autoconfigure.batch.JobExecutionExitCodeGenerator; 
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; 
import org.springframework.boot.context.properties.EnableConfigurationProperties; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.jdbc.core.JdbcOperations; 

import javax.sql.DataSource; 

/** 
* I'm using the same annotations as defined in BatchAutoConfiguration... 
*/ 
@Configuration 
@ConditionalOnClass({ JobLauncher.class, DataSource.class, JdbcOperations.class }) 
@AutoConfigureAfter(HibernateJpaAutoConfiguration.class) 
@ConditionalOnBean(JobLauncher.class) 
@EnableConfigurationProperties(BatchProperties.class) 

// ... but I add @AutoConfigureBefore(BatchAutoConfiguration.class) to take precedence over BatchAutoConfiguration 
@AutoConfigureBefore(BatchAutoConfiguration.class) 
public class JavabatchAutoConfiguration { 

    @Bean 
    @ConditionalOnMissingBean 
    @ConditionalOnBean(DataSource.class) 
    public BatchDatabaseInitializer batchDatabaseInitializer() { 
     System.out.println("Entering overwritten batchDatabaseInitializer"); 
     return new BatchDatabaseInitializer(); 
    } 

    @Bean 
    @ConditionalOnMissingBean 
    public ExitCodeGenerator jobExecutionExitCodeGenerator() { 
     System.out.println("Entering overwritten jobExecutionExitCodeGenerator"); 
     return new JobExecutionExitCodeGenerator(); 
    } 
} 

Как уже упоминалось в коде, я использую те же самые annotions для класса и методов, так как они definend в BatchAutoConfiguration.class. Только одно: @AutoConfigureBefore(BatchAutoConfiguration.class). Поскольку это должно иметь приоритет над BatchAutoConfiguration, я предположил, что это будет «перезаписывать» оригинал.

Для теста я использую следующий pom.xml:

<?xml version="1.0" encoding="UTF-8"?> 

<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
     http://maven.apache.org/xsd/maven-4.0.0.xsd"> 


    <modelVersion>4.0.0</modelVersion> 

    <groupId>ch.test.autoconfig</groupId> 
    <artifactId>auto_config_test</artifactId> 
    <version>1.0-SNAPSHOT</version> 

    <parent> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-parent</artifactId> 
     <version>1.2.3.RELEASE</version> 
    </parent> 

    <dependencies> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-batch</artifactId> 
     </dependency> 
    </dependencies> 
</project> 

И я использую эту простую работу с основным методом:

package ch.test.autoconfig; 

import org.springframework.batch.core.Job; 
import org.springframework.batch.core.Step; 
import org.springframework.batch.core.StepContribution; 
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; 
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; 
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; 
import org.springframework.batch.core.scope.context.ChunkContext; 
import org.springframework.batch.core.step.tasklet.Tasklet; 
import org.springframework.batch.repeat.RepeatStatus; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.context.annotation.Bean; 

/** 
* Created by U802552 on 01.06.2015. 
*/ 
@SpringBootApplication 
@EnableBatchProcessing 
public class MainJob { 

    @Autowired 
    private JobBuilderFactory jobs; 

    @Autowired 
    private StepBuilderFactory steps; 

    @Bean 
    protected Tasklet tasklet() { 
     return new Tasklet() { 
      public RepeatStatus execute(StepContribution contribution, 
             ChunkContext context) { 
       return RepeatStatus.FINISHED; 
      } 
     }; 
    } 

    @Bean 
    public Job job() throws Exception { 
     return this.jobs.get("job").start(step1()).build(); 
    } 

    @Bean 
    protected Step step1() throws Exception { 
     return this.steps.get("step1").tasklet(tasklet()).build(); 
    } 

    public static void main(String[] args) throws Exception { 
     // switch on Auto-Configuration-Report 
     System.setProperty("debug","true"); 
     SpringApplication.run(MainJob.class, args); 
    } 
} 

Я ожидал бы, что мой вызывается два перезаписанных метода, но, как указывается в описании Auto-Configuration-Report, мой класс JavabatchAutoConfiguration имеет отрицательное соответствие из-за отсутствующего экземпляра «JobLauncher». Как отмечается в отчете, исходный класс BatchAutoConfiguration имеет положительное совпадение для того же ConditionalOnBean чек.

Если я прокомментирую @ConditionalOnBean(JobLauncher.class) по классу и @ConditionalOnBean(DataSource.class) на batchDatabaseInitializer -метод, все работает должным образом.

У кого-нибудь есть объяснение этого поведения?

Благодаря Hansjörg

+0

Вы делаете это способ сложным ... Просто добавьте 2 боба этого типа 'BatchDatabaseInitializer' и' ExitCodeGenerator'. Автоматическая конфигурация Spring Batch будет автоматически обнаруживать их и использовать вместо них значения по умолчанию. Вам не нужны все условные обозначения и настройка после и т. Д. –

ответ

3

Вы делаете это путь к сложному. Единственное, что вам нужно сделать, это создать конфигурацию, которая определяет 2 конкретных компонента, которые вы хотите использовать.

@Configuration 
public class MyBatchConfiguration { 

    @Bean 
    public ExitCodeGenerator myExitCodeGenerator() { 
     return new MyExitCodeGenerator(); 
    } 

    @Bean 
    public BatchDatabaseInitializer myBatchDatabaseInitializer() { 
     return new MyBatchDatabaseInitializer(); 
    } 

} 

Это все, что вам нужно.

Смежные вопросы