Spring @Scheduled Demo

原创转载请注明出处:http://agilestyle.iteye.com/blog/2327299

Project Directory

Maven Dependency

<?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/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>org.fool</groupId>
	<artifactId>springschedule</artifactId>
	<name>springschedule</name>
	<packaging>war</packaging>
	<version>1.0.0-BUILD-SNAPSHOT</version>

	<properties>
		<org.springframework-version>4.2.8.RELEASE</org.springframework-version>
	</properties>
	<dependencies>
		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-jpa</artifactId>
			<version>1.10.3.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>4.3.11.Final</version>
		</dependency>

		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.8.1</version>
		</dependency>

		<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
			<version>19.0</version>
		</dependency>

		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.4</version>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>1.7.21</version>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-simple</artifactId>
			<version>1.7.21</version>
		</dependency>

		<!-- @Inject -->
		<dependency>
			<groupId>javax.inject</groupId>
			<artifactId>javax.inject</artifactId>
			<version>1</version>
		</dependency>

		<!-- Servlet -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>javax.servlet.jsp-api</artifactId>
			<version>2.3.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.39</version>
		</dependency>

		<dependency>
			<groupId>org.hsqldb</groupId>
			<artifactId>hsqldb</artifactId>
			<version>2.3.4</version>
		</dependency>

		<dependency>
			<groupId>joda-time</groupId>
			<artifactId>joda-time</artifactId>
			<version>2.9.4</version>
		</dependency>

		<!-- Test -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.5.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
					<compilerArgument>-Xlint:all</compilerArgument>
					<showWarnings>true</showWarnings>
					<showDeprecation>true</showDeprecation>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.eclipse.jetty</groupId>
				<artifactId>jetty-maven-plugin</artifactId>
				<version>9.3.11.v20160721</version>
				<configuration>
					<scanIntervalSeconds>10</scanIntervalSeconds>
					<httpConnector>
						<port>8888</port>
					</httpConnector>
					<webApp>
						<contextPath>/springschedule</contextPath>
					</webApp>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

  

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="WebApp_ID" version="3.0">

	<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring/root-context.xml</param-value>
	</context-param>

	<!-- Creates the Spring Container shared by all Servlets and Filters -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- Processes application requests -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

</web-app>

root-context.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<!-- Root Context: defines shared resources visible to all other web components -->
		
</beans>

servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

	<task:annotation-driven executor="myExecutor" scheduler="myScheduler" />
	<task:executor id="myExecutor" pool-size="5" />
	<task:scheduler id="myScheduler" pool-size="10" />

	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources 
		directory -->
	<resources mapping="/resources/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>

	<context:component-scan base-package="org.fool.springschedule" />

</beans:beans>

schema.sql

DROP TABLE IF EXISTS CAR;

CREATE TABLE CAR (
ID INT NOT NULL AUTO_INCREMENT, 
LICENSE_PLATE VARCHAR(20) NOT NULL, 
MANUFACTURER VARCHAR(20) NOT NULL, 
MANUFACTURE_DATE DATE NOT NULL, 
AGE INT NOT NULL DEFAULT 0, 
VERSION INT NOT NULL DEFAULT 0, 
UNIQUE UQ_CAR_1 (LICENSE_PLATE), 
PRIMARY KEY (ID)
);

insert into car (license_plate, manufacturer, manufacture_date) values ('LICENSE-1001', 'Ford', '1980-07-30');
insert into car (license_plate, manufacturer, manufacture_date) values ('LICENSE-1002', 'Toyota', '1992-12-30');
insert into car (license_plate, manufacturer, manufacture_date) values ('LICENSE-1003', 'BMW', '2003-1-6');

db.properties

#Database Configuration
#jdbc.driver=org.hsqldb.jdbcDriver
#jdbc.url=jdbc:hsqldb:mem:testdb;shutdown=false
#jdbc.username=sa
#jdbc.password=
jdbc.databaseName=springdata
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/${jdbc.databaseName}?useUnicode=true&amp;characterEncoding=UTF-8&useSSL=false
jdbc.username=root
jdbc.password=123456

#Hibernate Configuration
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.format_sql=true
hibernate.ejb.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy
hibernate.show_sql=false
#hibernate.hbm2ddl.auto=create-drop

DALConfig.java

package org.fool.springschedule.config;

import java.util.Properties;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories("org.fool.springschedule.repository")
@PropertySource("classpath:META-INF/db.properties")
@ComponentScan("org.fool.springschedule")
public class DALConfig {

	@Value("${jdbc.driver}")
	private String jdbcDriver;

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

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

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

	@Value("${hibernate.dialect}")
	private String hibernateDialect;

	@Value("${hibernate.format_sql}")
	private String hibernateFormatSql;

	@Value("${hibernate.ejb.naming_strategy}")
	private String hibernateEjbNamingStrategy;

	@Value("${hibernate.show_sql}")
	private String hibernateShowSql;

	@Bean
	public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfig() {
		return new PropertySourcesPlaceholderConfigurer();
	}

	@Bean
	public DataSource dataSource() {
		final DriverManagerDataSource dataSource = new DriverManagerDataSource();
		dataSource.setDriverClassName(jdbcDriver);
		dataSource.setUrl(jdbcUrl);
		dataSource.setUsername(jdbcUsername);
		dataSource.setPassword(jdbcPassword);

		return dataSource;
	}

	@Bean
	public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws ClassNotFoundException {
		LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();

		Properties jpaProperties = new Properties();
		jpaProperties.put("hibernate.dialect", hibernateDialect);
		jpaProperties.put("hibernate.format_sql", hibernateFormatSql);
		jpaProperties.put("hibernate.ejb.naming_strategy", hibernateEjbNamingStrategy);
		jpaProperties.put("hibernate.show_sql", hibernateShowSql);
		entityManagerFactoryBean.setJpaProperties(jpaProperties);
		entityManagerFactoryBean.setDataSource(dataSource());
		entityManagerFactoryBean.setPackagesToScan("org.fool.springschedule.domain");
		entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());

		return entityManagerFactoryBean;
	}

	@Bean
	public JpaTransactionManager transactionManager() throws ClassNotFoundException {
		JpaTransactionManager transactionManager = new JpaTransactionManager();

		transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());

		return transactionManager;
	}
}

Car.java

package org.fool.springschedule.domain;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Version;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

@Entity
@Table(name="car")
public class Car {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "ID")
	private Long id;

	@Column(name = "LICENSE_PLATE")
	private String licensePlate;

	@Column(name = "MANUFACTURER")
	private String manufacturer;

	@Column(name = "MANUFACTURE_DATE")
	private Date manufactureDate;

	@Column(name = "AGE")
	private int age;

	@Version
	private int version;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getLicensePlate() {
		return licensePlate;
	}

	public void setLicensePlate(String licensePlate) {
		this.licensePlate = licensePlate;
	}

	public String getManufacturer() {
		return manufacturer;
	}

	public void setManufacturer(String manufacturer) {
		this.manufacturer = manufacturer;
	}

	public Date getManufactureDate() {
		return manufactureDate;
	}

	public void setManufactureDate(Date manufactureDate) {
		this.manufactureDate = manufactureDate;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public int getVersion() {
		return version;
	}

	public void setVersion(int version) {
		this.version = version;
	}

	@Override
	public String toString() {
		return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
	}

}

CarRepository.java

package org.fool.springschedule.repository;

import org.fool.springschedule.domain.Car;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface CarRepository extends CrudRepository<Car, Long> {

}

CarService.java

package org.fool.springschedule.service;

import java.util.List;

import org.fool.springschedule.domain.Car;

public interface CarService {
	List<Car> findAll();

	Car save(Car car);

	void updateCarAgeJob();
}

CarServiceImpl.java

package org.fool.springschedule.service.impl;

import java.util.List;

import javax.inject.Inject;

import org.fool.springschedule.domain.Car;
import org.fool.springschedule.repository.CarRepository;
import org.fool.springschedule.service.CarService;
import org.joda.time.DateTime;
import org.joda.time.Years;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;

@Service
@Transactional
public class CarServiceImpl implements CarService {

	private final Logger logger = LoggerFactory.getLogger(CarServiceImpl.class);

	@Inject
	private CarRepository carRepository;

	@Override
	@Transactional(readOnly = true)
	public List<Car> findAll() {
		return Lists.newArrayList(carRepository.findAll());
	}

	@Override
	public Car save(Car car) {
		return carRepository.save(car);
	}

	@Override
	@Scheduled(fixedDelay = 10000)
	public void updateCarAgeJob() {
		List<Car> cars = findAll();
		DateTime currentDate = DateTime.now();

		logger.info("Car age update job started");

		for (Car car : cars) {
			int age = Years.yearsBetween(new DateTime(car.getManufactureDate()), currentDate).getYears();
			car.setAge(age);
			save(car);

			logger.info("Car age update--- " + car);
		}

		logger.info("Car age update job completed successfully");
	}

}

Test

SpringScheduleTest.java

package org.fool.springschedule.test;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringScheduleTest {

	public static void main(String[] args) {
		AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml");
		
		while (true) {

		}
	}

}

run it


 

Asynchronous Task Execution in Spring

AsyncService.java

package org.fool.springschedule.service;

import java.util.concurrent.Future;

public interface AsyncService {
	void asyncTask();

	Future<String> asyncWithReturn(String name);
}

AsyncServiceImpl.java

package org.fool.springschedule.service.impl;

import java.util.concurrent.Future;

import org.fool.springschedule.service.AsyncService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;

@Service
public class AsyncServiceImpl implements AsyncService {

	private final Logger logger = LoggerFactory.getLogger(AsyncServiceImpl.class);

	@Override
	@Async
	public void asyncTask() {
		logger.info("Start execution of async. task");

		try {
			Thread.sleep(10000);
		} catch (Exception ex) {
			ex.printStackTrace();
		}

		logger.info("Complete execution of async. task");
	}

	@Override
	@Async
	public Future<String> asyncWithReturn(String name) {
		logger.info("Start execution of async. task with return");

		try {
			Thread.sleep(5000);
		} catch (Exception ex) {
			ex.printStackTrace();
		}

		logger.info("Complete execution of async. task with return");
		return new AsyncResult<String>("Hello: " + name);
	}

}

Test

SpringAsyncTest.java

package org.fool.springschedule.test;

import java.util.concurrent.Future;

import org.fool.springschedule.service.AsyncService;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringAsyncTest {

	public static void main(String[] args) {
		AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml");

		AsyncService asyncService = ctx.getBean(AsyncService.class);

		for (int i = 0; i < 5; i++) {
			asyncService.asyncTask();
		}

		Future<String> result1 = asyncService.asyncWithReturn("Baidu");
		Future<String> result2 = asyncService.asyncWithReturn("Alibaba");
		Future<String> result3 = asyncService.asyncWithReturn("Tencent");

		try {
			Thread.sleep(6000);
			System.out.println("Result1: " + result1.get());
			System.out.println("Result2: " + result2.get());
			System.out.println("Result3: " + result3.get());
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		
	}
}

run it


 

Reference 

Apress.Pro Spring 4th Edition.2014 - CHAPTER 11 Task Scheduling in Spring

猜你喜欢

转载自agilestyle.iteye.com/blog/2327299
今日推荐