23 Haziran 2020 Salı

SpringBoot DataSourceAutoConfiguration

Örnek - DataSourceAutoConfiguration Yapmamak
Şöyle yaparız
spring.autoconfigure.exclude=
  org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, \
  org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, \
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration
Örnek - İki Tane DataSource
application.properties şöyle olsun
# Datasource - Secondary
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true


# Datasource - Primary
spring.hello.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.hello.datasource.url=jdbc:mysql://localhost:3306/batchmetadata
spring.hello.datasource.username=root
spring.hello.datasource.password=root


#spring.batch.table-prefix=batchmetadata.BATCH_
spring.batch.initialize-schema=always
spring.batch.job.enabled=false
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl

#https://stackoverflow.com/questions/28275448/multiple-data-source-and-schema-creation-in-spring-boot
Elimizde şöyle bir kod olsun.
@Configuration
public class DatabaseConfig {
  @Autowired
  private Environment env;

  // For Test schema
  @Bean(name="secondaryDS")
  @ConfigurationProperties(prefix="spring.datasource")
  public DataSource getSeconadaryBatchDataSource(){
    return DataSourceBuilder.create()
      .url(env.getProperty("spring.datasource.url"))
      .driverClassName(env.getProperty("spring.datasource.driver-class-name"))
      .username(env.getProperty("spring.datasource.username"))
      .password(env.getProperty("spring.datasource.password"))
      .build();
}


  // For "batchmetadata" tables
  @Bean(name="primaryDS")
  @Primary
  @ConfigurationProperties(prefix="spring.hello.datasource")
  public DataSource getPrimaryBatchDataSource(){
    return DataSourceBuilder.create()
      .url(env.getProperty("spring.hello.datasource.url"))
      .driverClassName(env.getProperty("spring.hello.datasource.driver-class-name"))
      .username(env.getProperty("spring.hello.datasource.username"))
      .password(env.getProperty("spring.hello.datasource.password"))
      .build();
  }
...
}
Şöyle yaparız
@Bean(name = "primaryEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory
  (EntityManagerFactoryBuilder builder) {
  Map<String, Object> properties = new HashMap<String, Object>();
  properties.put("hibernate.hbm2ddl.auto", "update");
  return builder
    dataSource(getSeconadaryBatchDataSource())
    .packages("com.example.model")
    .persistenceUnit("default")
    .properties(properties)
    .build();
}

SpringBatch SimpleJobLauncher Sınıfı - Job Nesnesini Belirtilen JobParameters İle Çalıştırır

Giriş
run() metodu aracılığıyla belirtilen Job nesnesini belirtilen JobParameters ile çalıştırır.

Tanımlama
Örnek
Şöyle yaparız.
<bean id="jobLauncher"
     class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
    <property name="jobRepository" ref="jobRepository" />
    <property name="taskExecutor">
        <bean class="org.springframework.core.task.SimpleAsyncTaskExecutor" />
    </property>
</bean>
Örnek
Şöyle yaparız.
@Bean
public JobLauncher simpleJobLauncher() throws Exception {
  SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
  ...
  return jobLauncher;
}
Kullanım
Örnek
Elimizde bir tane Job bean olsun. Job nesnesi normalde bean olmak zorunda değil.
@Bean
public Step step1() {
  return stepBuilderFactory.get("step1")
    .<Customer, Customer> chunk(1000)
    .reader(customerItemReader())
    .writer(customerItemWriter())
    .build();
}


@Bean
public Job job() {
  return jobBuilderFactory.get("job")
    .start(step1())
    .build();
}  
Şöyle yaparız
@EnableBatchProcessing
public class SpringBatchApplication implements CommandLineRunner {

  @Autowired
  private JobLauncher jobLauncher;

  @Autowired
  private Job job;

  public static void main(String[] args) {
    SpringApplication.run(SpringBatchApplication.class, args);
  }

  @Override
  public void run(String... args) throws Exception {
    JobParameters jobParameters = new JobParametersBuilder()
      .addString("UUID", UUID.randomUUID().toString())
      .toJobParameters();

    JobExecution execution = jobLauncher.run(job, jobParameters);
    System.out.println("STATUS :: "+execution.getStatus());
   }
}
constructor
Şöyle yaparız.
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
afterPropertiesSet metodu
Şöyle yaparız.
jobLauncher.afterPropertiesSet();
run metodu
Metodun imzası şöyle. JobExecution nesnesi döner.
public JobExecution run(Job job, JobParameters jobParameters)
  throws JobExecutionAlreadyRunningException, JobRestartException,
         JobInstanceAlreadyCompleteException, JobParametersInvalidException
Örnek
Şöyle yaparız
Job job =  ...;
JobParameters jobParameters = ...;
try {
  JobExecution jobExecution = jobLauncher.run(job, jobParameters);
} catch (JobExecutionAlreadyRunningException | JobRestartException
   | JobInstanceAlreadyCompleteException | JobParametersInvalidException e) {
  ...
}
Örnek
Elimizde şöyle bir kod olsun
JobParametersBuilder paramsBuilder = new JobParametersBuilder();
paramsBuilder.addString("delimiter", "yourCustomDelimiter");
Şöyle yaparız.
jobLauncher.run(job, paramsBuilder.toJobParameters());
Örnek
Controller içinde şöyle yaparız.
@Autowired
JobLauncher jobLauncher;

@RequestMapping(value="/trigger-job", method = RequestMethod.GET)
public Long workHard() throws Exception {
  JobParameters jobParameters = new JobParametersBuilder().
    addLong("time", System.currentTimeMillis())
    .toJobParameters();
  JobExecution jobExecution = jobLauncher.run(myJob, jobParameters);
  ...
}
setJobRepository metodu
Örnek
Şöyle yaparız.
@Configuration
public class BatchConfig {

  @Autowired
  JobRepository jobRepository;


  @Bean
  public JobLauncher simpleJobLauncher() throws Exception {
    SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
    jobLauncher.setJobRepository(jobRepository);
    ...
    return jobLauncher;
  }
}
setTaskExecutor metodu
Örnek
Şöyle yaparız.
jobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor());
Örnek
Şöyle yaparız.
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
  ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
  taskExecutor.setCorePoolSize(15);
  taskExecutor.setMaxPoolSize(20);
  taskExecutor.setQueueCapacity(30);
  return taskExecutor;
}

@Bean
public JobLauncher jobLauncher(ThreadPoolTaskExecutor taskExecutor,
  JobRepository jobRepository) {
  SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
  jobLauncher.setTaskExecutor(taskExecutor);
  jobLauncher.setJobRepository(jobRepository);
  return jobLauncher;
}