1、基于springboot的项目开启自动配置
- package com.plateno.booking.sync.vienna;
- import javax.annotation.PostConstruct;
- import javax.jms.ConnectionFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
- import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
- import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.ImportResource;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
- import org.springframework.jms.config.JmsListenerContainerFactory;
- import org.springframework.jms.core.JmsTemplate;
- import org.springframework.jms.support.converter.MessageConverter;
- import org.springframework.scheduling.annotation.EnableAsync;
- import org.springframework.scheduling.annotation.EnableScheduling;
- import com.plateno.booking.sync.vienna.annotation.EnableMysql;
- import com.plateno.booking.sync.vienna.annotation.EnableRedis;
- import com.plateno.booking.sync.vienna.jms.messageconverter.PlatenoMessageConverter;
- import com.plateno.booking.sync.vienna.util.BookingRedisHelper;
- import com.plateno.booking.sync.vienna.util.SpringContextUtils;
- //@EnableMysql
- //@EnableRedis
- //开启自动配置
- @SpringBootApplication(exclude = {
- DataSourceAutoConfiguration.class,
- RedisAutoConfiguration.class
- }, scanBasePackageClasses = {
- BookingSyncVienna.class })
- public class BookingSyncVienna {
- public static void main(String[] args) {
- SpringApplication springApplication = new SpringApplication(BookingSyncVienna.class);
- springApplication.run(args);
- }
- @Autowired
- JmsTemplate jmsTemplate;
- @Bean
- MessageConverter messageConverter() {
- return new PlatenoMessageConverter();
- }
- @Bean
- SpringContextUtils springContextUtils() {
- return new SpringContextUtils();
- }
- @PostConstruct
- public void init() {
- this.jmsTemplate.setMessageConverter(messageConverter());
- }
- /**
- * 创建默认的listerFactory
- * see:JmsListenerAnnotationBeanPostProcessor->static final String DEFAULT_JMS_LISTENER_CONTAINER_FACTORY_BEAN_NAME = "jmsListenerContainerFactory";
- * @param connectionFactory
- * @param configurer
- * @return
- */
- @Bean(name="jmsListenerContainerFactory")
- public JmsListenerContainerFactory<?> jmsListenerContainerFactory(ConnectionFactory connectionFactory,
- DefaultJmsListenerContainerFactoryConfigurer configurer) {
- DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
- factory.setMessageConverter(messageConverter());
- configurer.configure(factory, connectionFactory);
- return factory;
- }
- /* @Bean
- @Autowired
- public BookingRedisHelper redisHelper(RedisTemplate redisTemplate) {
- BookingRedisHelper bookingRedisHelper = new BookingRedisHelper();
- bookingRedisHelper.setRedisTemplate(redisTemplate);
- return bookingRedisHelper;
- }
- */
- /*
- * @Bean public DefaultJmsListenerContainerFactory
- * listenerContainerFactory() { DefaultJmsListenerContainerFactory factory =
- * new DefaultJmsListenerContainerFactory();
- * factory.setConnectionFactory(connectionFactory());
- * factory.setMessageConverter(objectConverter());
- * factory.setConcurrency("5"); return factory; }
- */
- /*
- * @Bean public ConnectionFactory connectionFactory(){
- * PooledConnectionFactory pooledConnectionFactory = new
- * PooledConnectionFactory(); ActiveMQConnectionFactory mqConnectionFactory
- * = new ActiveMQConnectionFactory();
- * mqConnectionFactory.setBrokerURL(brokerUrl);
- * mqConnectionFactory.setUseAsyncSend(true);
- * mqConnectionFactory.setOptimizeAcknowledgeTimeOut(3000);
- * pooledConnectionFactory.setConnectionFactory(mqConnectionFactory);
- * pooledConnectionFactory.setMaxConnections(20);
- * mqConnectionFactory.setTransactedIndividualAck(true); return
- * pooledConnectionFactory; }
- */
- }
2、创建作业类
- package com.plateno.booking.sync.vienna.test;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
- import org.springframework.scheduling.annotation.Async;
- import org.springframework.scheduling.annotation.Scheduled;
- import org.springframework.stereotype.Component;
- import com.plateno.booking.sync.vienna.properties.CronProperties;
- @Component
- @ConditionalOnProperty(prefix = "", name = "test", havingValue = "true")
- public class TestJob {
- private static Logger logger = LoggerFactory.getLogger(TestJob.class);
- @Scheduled(cron="0/2 * * * * ?")
- @Async//异步执行,配合线程池实现并发
- public void test(){
- System.err.println("---------------------");
- System.err.println("a");
- logger.error(Thread.currentThread().getName());
- System.err.println("---------------------");
- try {
- Thread.sleep(20000);//执行睡眠,这样如果并发执行,那么上面的打印会2秒执行一次,而下面的ffff则会22秒打印一次
- System.out.println("ffff");
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- /*@Scheduled(cron="0/1 * * * * ?")
- public void test1(){
- System.err.println("---------------------");
- System.err.println("b");
- logger.error(Thread.currentThread().getName());
- System.err.println("---------------------");
- }*/
- }
3、定义线程池配置文件(@enableSchedulling@scheduled默认是基于单线程),多线程并发需要配置xml
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:task="http://www.springframework.org/schema/task"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-4.2.xsd
- http://www.springframework.org/schema/task
- http://www.springframework.org/schema/task/spring-task-4.2.xsd">
- <task:scheduler id="scheduler" pool-size="10" />
- <task:executor id="executor" keep-alive="7200" pool-size="100-200"
- queue-capacity="500" rejection-policy="CALLER_RUNS" />
- <task:annotation-driven executor="executor"
- scheduler="scheduler" />
- </beans>
同时,如果想使用注解开发
配置类加上@EnableAsync即可,本质上都是创建AsyncAnnotationBeanPostProcessor对象,另外如果要自定义excutor和exceptionHandller,可以参考@EnableAsync源码
注释:
- /**
- * Enables Spring's asynchronous method execution capability, similar to functionality
- * found in Spring's {@code <task:*>} XML namespace.
- *
- * <p>To be used on @{@link Configuration} classes as follows, where {@code MyAsyncBean}
- * is a user-defined type with one or more methods annotated with either Spring's
- * {@code @Async} annotation, the EJB 3.1 {@code @javax.ejb.Asynchronous} annotation,
- * or any custom annotation specified via the {@link #annotation} attribute.
- *
- * <pre class="code">
- * @Configuration
- * @EnableAsync
- * public class AppConfig {
- *
- * @Bean
- * public MyAsyncBean asyncBean() {
- * return new MyAsyncBean();
- * }
- * }</pre>
- *
- * <p>The {@link #mode} attribute controls how advice is applied; if the mode is
- * {@link AdviceMode#PROXY} (the default), then the other attributes control the behavior
- * of the proxying.
- *
- * <p>Note that if the {@linkplain #mode} is set to {@link AdviceMode#ASPECTJ}, then the
- * value of the {@link #proxyTargetClass} attribute will be ignored. Note also that in
- * this case the {@code spring-aspects} module JAR must be present on the classpath.
- *
- * <p>By default, Spring will be searching for an associated thread pool definition:
- * either a unique {@link org.springframework.core.task.TaskExecutor} bean in the context,
- * or an {@link java.util.concurrent.Executor} bean named "taskExecutor" otherwise. If
- * neither of the two is resolvable, a {@link org.springframework.core.task.SimpleAsyncTaskExecutor}
- * will be used to process async method invocations. Besides, annotated methods having a
- * {@code void} return type cannot transmit any exception back to the caller. By default,
- * such uncaught exceptions are only logged.
- *
- * <p>To customize all this, implement {@link AsyncConfigurer} and provide:
- * <ul>
- * <li>your own {@link java.util.concurrent.Executor Executor} through the
- * {@link AsyncConfigurer#getAsyncExecutor getAsyncExecutor()} method, and</li>
- * <li>your own {@link org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler
- * AsyncUncaughtExceptionHandler} through the {@link AsyncConfigurer#getAsyncUncaughtExceptionHandler
- * getAsyncUncaughtExceptionHandler()}
- * method.</li>
- * </ul>
- *
- * <pre class="code">
- * @Configuration
- * @EnableAsync
- * public class AppConfig implements AsyncConfigurer {
- *
- * @Bean
- * public MyAsyncBean asyncBean() {
- * return new MyAsyncBean();
- * }
- *
- * @Override
- * public Executor getAsyncExecutor() {
- * ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
- * executor.setCorePoolSize(7);
- * executor.setMaxPoolSize(42);
- * executor.setQueueCapacity(11);
- * executor.setThreadNamePrefix("MyExecutor-");
- * executor.initialize();
- * return executor;
- * }
- *
- * @Override
- * public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
- * return MyAsyncUncaughtExceptionHandler();
- * }
- * }</pre>
- *
- * <p>If only one item needs to be customized, {@code null} can be returned to
- * keep the default settings. Consider also extending from {@link AsyncConfigurerSupport}
- * when possible.
- *
- * <p>Note: In the above example the {@code ThreadPoolTaskExecutor} is not a fully managed
- * Spring bean. Add the {@code @Bean} annotation to the {@code getAsyncExecutor()} method
- * if you want a fully managed bean. In such circumstances it is no longer necessary to
- * manually call the {@code executor.initialize()} method as this will be invoked
- * automatically when the bean is initialized.
- *
- * <p>For reference, the example above can be compared to the following Spring XML
- * configuration:
- *
- * <pre class="code">
- * {@code
- * <beans>
- *
- * <task:annotation-driven executor="myExecutor" exception-handler="exceptionHandler"/>
- *
- * <task:executor id="myExecutor" pool-size="7-42" queue-capacity="11"/>
- *
- * <bean id="asyncBean" class="com.foo.MyAsyncBean"/>
- *
- * <bean id="exceptionHandler" class="com.foo.MyAsyncUncaughtExceptionHandler"/>
- *
- * </beans>
- * }</pre>
参考:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html
执行结果:
图片无法显示:睡眠之前的2秒打印一次,睡眠之后的22秒打印一次