单独的配置类时无法自动装配bean

时间:2016-01-14 00:50:38

标签: spring spring-batch

我有一个JavaConfig可配置的Spring Batch作业。主作业配置文件是CrawlerJobConfiguration。在此之前,我在此类中拥有所有配置(基础结构,自动装配的bean等),并且它可以正常工作。所以我决定将作业配置与autowired beans和infracstruture beans配置分开,并创建另外两个配置类Beans和MysqlInfrastructureConfiguration。

但是现在我的工作遇到了问题。当应用程序尝试使用指示自动装配不起作用的自动装配字段时,我收到NullPointerException。

我在创建自动装配的bean的方法中放置了一个断点,以确保它们被调用并且确实是,所以我无法意识到可能存在的问题。

java.lang.NullPointerException: null
    at br.com.alexpfx.supermarket.batch.tasklet.StartCrawlerTasklet.execute(StartCrawlerTasklet.java:27) ~[classes/:na]
    at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:406) ~[spring-batch-core-3.0.6.RELEASE.jar:3.0.6.RELEASE]

主要工作配置类:

@Configuration
@EnableBatchProcessing
public class CrawlerJobConfiguration {


    @Autowired
    private InfrastructureConfiguration infrastructureConfiguration;

    @Autowired
    private StepBuilderFactory steps;
    @Autowired
    Environment environment;


    @Bean
    public Job job(JobBuilderFactory jobs) {
        Job theJob = jobs.get("job").start(crawlerStep()).next(processProductStep()).build();
        ((AbstractJob) theJob).setRestartable(true);
        return theJob;

    }

    @Bean
    public Step crawlerStep() {
        TaskletStep crawlerStep = steps.get("crawlerStep").tasklet(crawlerTasklet()).build();
        crawlerStep.setAllowStartIfComplete(true);
        return crawlerStep;
    }

    @Bean
    public Step processProductStep() {
        TaskletStep processProductStep = steps.get("processProductStep")
                .<TransferObject, Product>chunk(10)
                .reader(reader())
                .processor(processor())
                .writer(writer())
                .build();
        processProductStep.setAllowStartIfComplete(true);
        return processProductStep;
    }

    private Tasklet crawlerTasklet() {
        return new StartCrawlerTasklet();
    }

    private ItemProcessor<TransferObject, Product> processor() {
        return new ProductProcessor();
    }

    private ItemReader<TransferObject> reader() {
        return new ProductItemReader();
    }

    private ItemWriter<Product> writer() {
        return new HibernateProductsItemWriter();
    }        
}

Beans配置类:

@Configuration
@EnableBatchProcessing
public class Beans {

    @Bean
    public Crawler crawler() {
        return new RibeiraoCrawler(new UserAgentFactory());
    }

    @Bean
    public ProductBo productBo() {
        return new ProductBoImpl();
    }

    @Bean
    public ProductDao productDao() {
        return new ProductDaoImpl();
    }


    @Bean
    public CrawlerListener listener() {
        CrawlerListener listener = new RibeiraoListener();
        return listener;
    }

    @Bean
    public ProductList getProductList() {
        return new ProductList();
    }


}

MysqlInfrastructureConfiguration:

@Configuration
@EnableBatchProcessing
@PropertySource("classpath:database.properties")
@EnableJpaRepositories(basePackages = {"br.com.alexpfx.supermarket.domain"})
public class MysqlInfrastructureConfiguration implements InfrastructureConfiguration {

    @Value("${jdbc.url}")
    String url;

    @Value("${jdbc.driverClassName}")
    String driverClassName;

    @Value("${jdbc.username}")
    String username;

    @Value("${jdbc.password}")
    String password;

    @Bean
    @Override
    public DataSource getDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }


    @Bean
    @Override
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory());
        transactionManager.setDataSource(getDataSource());
        return transactionManager;
    }

    @Bean
    @Override
    public EntityManagerFactory entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(getDataSource());
        em.setPackagesToScan(new String[]{"br.com.alexpfx.supermarket.domain"});

        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        em.setJpaProperties(additionalJpaProperties());
        em.afterPropertiesSet();
        return em.getObject();
    }

    private Properties additionalJpaProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.hbm2ddl.auto", "create");
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
        properties.setProperty("hibernate.show_sql", "true");
        properties.setProperty("current_session_context_class", "thread");
        return properties;
    }


}

微进程:

public class StartCrawlerTasklet implements Tasklet {

    @Autowired
    private Crawler crawler;

    @Autowired
    private CrawlerListener listener;

    @Override
    public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
        crawler.setListener(listener);
        crawler.setStopCondition(new TimeLimitStopCondition(1, TimeUnit.MINUTES));
        crawler.crawl();
        return RepeatStatus.FINISHED;
    }

}

1 个答案:

答案 0 :(得分:1)

StartCrawlerTasklet使用autowired注释,因此它也应该是一个bean。所以改变你的代码:

private Tasklet crawlerTasklet() {
    return new StartCrawlerTasklet();
}

到bean定义:

@Bean
public Tasklet crawlerTasklet() {
    return new StartCrawlerTasklet();
}