правильная инициализация контекста весны - PullRequest
0 голосов
/ 02 октября 2019

У меня есть приложение Spring (не Springboot). Мне нужно запустить приложение триггера, используя задачи расписания, используя @Scheduled. Я использую конфигурацию пружин на основе аннотаций:

package kz.user.integration.configuration;

import org.apache.log4j.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
import org.springframework.jndi.JndiObjectFactoryBean;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;


@Configuration
@EnableWebMvc
@EnableScheduling
@ComponentScan(basePackages = {"kz.user.integration"})
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"kz.user.integration"})
public class SpringConfiguration {
    private final static Logger LOG = Logger.getLogger(SpringConfiguration.class);


    @Bean(name = "MyDataSource")
    public DataSource dataSource() {
        final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
        dsLookup.setResourceRef(true);
        DataSource dataSource = dsLookup.getDataSource("java:jboss/datasources/MyDB/");

        return dataSource;
    }

    @Bean
    public EntityManager entityManager() {
        return entityManagerFactory().getObject().createEntityManager();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        em.setJpaProperties(jpaMappingProps());
        em.setPackagesToScan("kz.user.integration.model.entity");
        return em;
    }

    @Bean
    Properties jpaMappingProps() {
        Properties p = new Properties();
        p.setProperty("hibernate.hbm2ddl.auto", "update");
        p.setProperty("show_sql", "true");
        p.setProperty("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
        return p;
    }

    @Bean(name = "transactionManager")
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory().getObject());
        return txManager;
    }

}

Это мой класс с заданием расписания:

package kz.user.integration.service;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;


@Component
public class ScheduledTasks {
    private final static Logger LOG = Logger.getLogger(ScheduledTasks.class);


    @Autowired
    EmailService emailService;


    @Scheduled(fixedRate = 120000)
    public void readTables() throws Exception {
        try {
           //some jobs
        } catch (Exception e) {
            LOG.error("job error: " + e);
            emailService.send("error", "reason " + e);
        }
    }
}

Но планирование не работает. Это работает, только если я создаю класс (в пакете, объявленном в @ComponentScan), который расширяет AbstractAnnotationConfigDispatcherServletInitializer и заставляет мою SpringConfiguration расширять WebMvcConfigurerAdapter. Зачем мне нужно расширение класса AbstractAnnotationConfigDispatcherServletInitializer, если я не использую Spring MVC. Я не мог найти никакого другого решения, как инициализировать весенний контекст и вызвать аннотированный метод @Scheduled. Итак, вопрос в том, как правильно инициализировать контекст Spring и запустить выполнение метода Scheduled?

...