背景:
最近,公司的项目是使用Gradle进行构建Web项目,为此需要写一份简单的Gradle教程作为构建项目文档。
Gradle项目构建脚本 -> build.gradle
// 创建Java项目插件,提供了所有构建和测试Java程序所需项目结构
apply plugin: 'java'
// 引入Maven插件,以便Gradle可以引用Maven仓库的Jar包
apply plugin: 'maven'
// 进行打包插件
apply plugin: 'war'
// Web项目服务器插件,此处配置后,不需再单独配置Web服务器
apply plugin: 'jetty'
// Web项目开发插件
apply plugin: 'eclipse'
// 启动jetty容器的配置参数
jettyRun {
// 自动热切换
reload = "automatic"
scanIntervalSeconds = 0
// http端口号
httpPort = 8088
// 停止jetty容器
stopPort = 8082
stopKey = "stopKey"
}
group = "com.suneee"
// 指定编译*.java文件的JDK版本
sourceCompatibility = 1.8
version = '1.0'
// Web项目示例工程
jar {
manifest {
attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version
// 题外话:Java项目,此处可以用来配置程序入口点
// attributes 'Main-Class':'com.suneee.**'
}
}
// 默认情况,Gradle没有定义任何资源库
repositories {
// 使用Maven的中央存储库
mavenCentral()
// 使用Maven的本地存储库
mavenLocal()
}
// 增加自定义的库
repositories {
flatDir{
// 项目目录下的lib文件夹
dirs 'lib'
}
}
// 解决Gradle编译时出现: 编码GBK的不可映射字符
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
// 解决项目Jar包依赖问题
dependencies {
// 编译时,加入项目目录下lib文件
compile fileTree(dir:'lib',include:'*.jar')
compile 'c3p0:c3p0:0.9.1.2'
compile 'mysql:mysql-connector-java:5.1.31'
compile 'org.springframework.data:spring-data-redis:1.3.4.RELEASE'
compile group: 'com.google.code.gson', name: 'gson', version: '2.7'
compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
testCompile "org.springframework:spring-test:4.1.0.RELEASE"
testCompile group: 'junit', name: 'junit', version: '4.+'
compile 'com.alibaba:dubbo:2.8.4a'
compile 'org.apache.zookeeper:zookeeper:3.4.8'
compile 'com.101tec:zkclient:0.8'
compile 'log4j:log4j:1.2.17'
compile group: 'javax.activation', name: 'activation', version: '1.1.1'
compile group: 'javax.mail', name: 'mail', version: '1.4.7'
compile group: 'org.quartz-scheduler', name: 'quartz', version: '1.7.2'
compile group: 'aspectj', name: 'aspectjweaver', version: '1.5.4'
compile group: 'org.hibernate', name: 'hibernate-core', version: '5.1.0.Final'
compile group: 'org.hibernate', name: 'hibernate-entitymanager', version: '5.1.0.Final'
compile group: 'org.springframework', name: 'spring-orm', version: '4.2.4.RELEASE'
}
test {
systemProperties 'property': 'value'
}
// 发布项目导出的Jar包到指定仓库
uploadArchives {
repositories {
flatDir {
dirs 'repos'
}
}
}
项目组使用的是eclipse进行开发,并且前后端进行完全分离架构。
作为项目后端的开发组成员,只需要开发Service层,Dao层即可,大大的减轻了后端开发组成员的任务,同时项目后端开发组成员比较对提供的API有过完整的单元的测试。
Talk is cheap,show me the code.
接口定义
// service layer
public interface HotelOrderService {
public Page extends HotelOrderVO> queryCheckin(CheckinHOCDto checkin);
public Page extends HotelOrderVO> queryDelivery(DeliveryOrderHOCDto delivery);
public Page extends HotelOrderVO> queryScheduledProcessing(ScheduledProcessingHOCDto scheduledProcessing);
public Page extends HotelOrderVO> queryScheduledSuccess(ScheduledSuccessHOCDto scheduledSuccess);
}
// dao layer
@FunctionalInterface
public interface HotelOrderQueryDao {
public List queryHotelOrder(Optional extends HotelOrderCondition> condition);
}
接口实现
// service layer
@Service("api-hotel-order")
public class HotelOrderServiceImpl implements HotelOrderService {
private static final Logger log = LoggerFactory.getLogger(HotelOrderServiceImpl.class);
@Autowired
private HotelOrderQuery hotelOrderQuery;
Function super TTbHotelOrderInfoT,? extends HotelOrderVO> mapper= x->{
HotelOrderVO t = new HotelOrderVO();
// TODO set vo filed value
return t;
};
private Page extends HotelOrderVO> setPageParams(T t){
Page extends HotelOrderVO> page=new Page<>();
if(Objects.nonNull(t)){
page.setPageSize(t.getPageSize());
page.setOffset(t.getStartIndex());
}
return page;
};
@SuppressWarnings("unchecked")
@Override
public Page extends HotelOrderVO> queryCheckin(CheckinHOCDto checkin) {
log.debug("Entering query checkin method...");
Page page = (Page) setPageParams(checkin);
page.setItems(hotelOrderQuery.queryCheckin(checkin).parallelStream().map(mapper).collect(Collectors.toList()));
return page;
}
@SuppressWarnings("unchecked")
@Override
public Page extends HotelOrderVO> queryDelivery(DeliveryOrderHOCDto delivery) {
log.debug("Entering query delivery method...");
Page page=(Page)setPageParams(delivery);
page.setItems(hotelOrderQuery.queryDeliveryOrder(delivery).parallelStream().map(mapper).collect(Collectors.toList()));
return page;
}
@SuppressWarnings("unchecked")
@Override
public Page extends HotelOrderVO> queryScheduledProcessing(ScheduledProcessingHOCDto scheduledProcessing) {
log.debug("Entering query scheduled processing method...");
Page page=(Page) setPageParams(scheduledProcessing);
page.setItems(hotelOrderQuery.queryScheduledProcessing(scheduledProcessing).parallelStream().map(mapper).collect(Collectors.toList()));
return page;
}
@SuppressWarnings("unchecked")
@Override
public Page extends HotelOrderVO> queryScheduledSuccess(ScheduledSuccessHOCDto scheduledSuccess) {
log.debug("Entering query scheduled success method...");
Page page=(Page) setPageParams(scheduledSuccess);
page.setItems(hotelOrderQuery.queryScheduledSuccess(scheduledSuccess).parallelStream().map(mapper).collect(Collectors.toList()));
return page;
}
}
// dao layer
@Repository("hotelOrderQuery")
public class HotelOrderQueryImpl implements HotelOrderQuery{
@SuppressWarnings("unused")
@Autowired
private HotelOrderQueryBus hotelOrderQueryBus;
/**
* 重载方法
* @param condition
* @return
*/
@Override
public List queryCheckin(CheckinHOCDto condition) {
return HotelOrderDaoFactory.getInstance().valueOf(HotelOrderType.QUERY_CHECKIN).of().queryHotelOrder(Optional.ofNullable(condition));
}
/**
* 重载方法
* @param condition
* @return
*/
@Override
public List queryDeliveryOrder(DeliveryOrderHOCDto condition) {
return HotelOrderDaoFactory.getInstance().valueOf(HotelOrderType.QUERY_DELIVERY_ORDER).of().queryHotelOrder(Optional.ofNullable(condition));
}
/**
* 重载方法
* @param condition
* @return
*/
@Override
public List queryScheduledProcessing(ScheduledProcessingHOCDto condition) {
return HotelOrderDaoFactory.getInstance().valueOf(HotelOrderType.QUERY_SCHEDULED_PROCESSING).of().queryHotelOrder(Optional.ofNullable(condition));
}
/**
* 重载方法
* @param condition
* @return
*/
@Override
public List queryScheduledSuccess(ScheduledSuccessHOCDto condition) {
return HotelOrderDaoFactory.getInstance().valueOf(HotelOrderType.QUERY_SCHEDULED_SUCCESS).of().queryHotelOrder(Optional.ofNullable(condition));
}
}
由于单元测试更多的是测试业务逻辑,这里不便公开。
主要是使用HttpClient进行单元测试的,并且必须先开启jettyRun的gradle task,将jetty服务器启动,才能进行远程单元测试。
单元测试的过程中,往往需要进行断点调试。为此,我们需要进行远程服务调试。
- 配置远程调试端口
配置完,点击Run即可完成.
-Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=9999,suspend=n
需要注意的是,address是远程调试的端口。将会在下面用到
- 配置本地调试远程服务IP,端口
最后,当项目开发完成之后,需要进行打包到生产环境中。执行此gradle task即可。
Have a good night :)