又是一个愚蠢的错误,皆因.xml而起
论java中的.xml到底有多坑?!
感觉自己都快哭了,再一次被.xml给坑了一下,这次坑的太狠了,一下子导致自己浪费了昨天一下午,一晚上,今天一上午和半个下午呀,中间的过程真的是乏善可陈呀,各种转折,各种离奇的错误,自己都崩溃了好多次,让我一一来诉说吧。
1、在springmvc分层结构中(分为mybatis层、service层、controller层)自己定义了一个定时器,定时器是定义在service的配置文件中的,文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.2.xsd" > <!-- 定义service -->
<!-- 扫描controller交给前段控制器,service包中的注解交给此配置扫描 -->
<context:component-scan base-package="service" > </context:component-scan>
<!-- 第二个扫描项bean包 -->
<context:component-scan base-package="bean" > </context:component-scan> <task:annotation-driven/> </beans>
代码中加粗的部分是定时器的关键,注意这里一定要配置在service层,如果配置到了spring-mvc.xml层,就没有反应,这也是我以前犯的一个愚蠢的错误,究其原因,这和springmvc运行的机理有关,如果没有得到合理的初始化,没有被扫描到都是执行不了的。
之后就可以在service层写定时器的代码了,其实也简单,但是写完之后一定要注意配置扫描,这个地方,因为整个service层都被扫描了,所以无论放在哪里都可以,也不用在.xml中配置了。
定时器的代码如下:
@Component
public class StatisticsTimer {
private static Logger logger = Logger.getLogger(StatisticsTimer.class); //定时器测试
@Scheduled(cron="0/20 * * * * ? ")
public void statisticsTimerCycle(){ System.out.println("============begining===============");
//一些代码
System.out.println("============end==============="); }
}
这里要注意加入的部分,之后运行程序,就可以看到每隔一段时间就打印出来一些东西了。
可是在大型项目中,定时器都是用来处理SQL语句的,也就是要进行数据库操作,这个时候,因为我是用的mybatis这个框架,其中配置之后就可以自动扫描来生成代码了,根本就不用我来配置,我就理所当然的使用依赖注入想要的语句,之后来查询数据库,可是一直报错,意思是说mybatis不能找到我要调用的查找方法,在这里我要说明一点,那些mapper以及相应的.xml都是我自己写的,因为自动生成的可能满足不了的我的要求,也正是因为这个原因我就悲剧了,还记得当时写这个东西是在我电脑出了点问题的时候,我没有在工程里面写,而是在一个文本编辑器中写的,这就造成了一些东西是我手打出来的,而不是复制的,这样就很容易错过一个或者两个字母,而这次我竟然真的是犯了这个错,就是因为我在.xml中少写了一个字母‘s’,而我当时不知道呀,再加上对自己的编码能力太自信了吧,想哭。。。
17-12-06-14-55-40-001-ERROR-[pool-1-thread-1]-Unexpected error occurred in scheduled task.
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): mapper.part.OrderStatisticsPartMapper.selectOrdersInfoByToday
at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:189)
at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:43)
at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:58)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:51)
at com.sun.proxy.$Proxy44.selectOrdersInfoByToday(Unknown Source)
at service.statistics.OrderStatisticsOperator.selectOrdersInfoByToday(OrderStatisticsOperator.java:25)
at service.timer.StatisticsTimer.statisticsTimerCycle(StatisticsTimer.java:55)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:64)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:53)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
@Autowired
private OrderStatisticsOperator orderStatisticsOperator;
首先我给大家看一下我的这些相关文件吧:
1.罪恶之源:OrderStatisticsPartMapper.xml,看到了吗,这就是我标出的那个我错的地方,其实是Orders而不是Order!!!!!!
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.part.OrderStatisticsPartMapper"> <resultMap id="order_statistics_part" type="pojo.part.OrderStatisticsPart">
<result column="order_id" jdbcType="VARCHAR" property="orderId" />
<result column="shop_account_id" jdbcType="INTEGER" property="shopAccountId" />
<result column="wating_start_time" jdbcType="VARCHAR" property="watingStartTime" />
<result column="waiting_end_time" jdbcType="VARCHAR" property="waitingEndTime" />
<result column="pay_total_price" jdbcType="DECIMAL" property="payTotalPrice" />
</resultMap> <select id="selectOrderInfoByToday" resultMap="order_statistics_part">
select order_id ,shop_account_id , wating_start_time , waiting_end_time , pay_total_price
from orders </select> </mapper>
2.对应的接口类:OrderStatisticsPartMapper
package service.statistics;
import java.util.List; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import pojo.part.OrderStatisticsPart;
import mapper.part.OrderStatisticsPartMapper; /**
* @author zyr
* 按日期查询当天商城消费订单信息
*/
public interface OrderStatisticsInterface { public List<OrderStatisticsPart> selectOrdersInfoByToday(String today_date);
}
3.OrderStatisticsOperator类,service层,对上面的方法进行封装
package service.statistics;
import java.util.List; import javax.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import pojo.part.OrderStatisticsPart;
import mapper.part.OrderStatisticsPartMapper; /**
* @author zyr
* 按日期查询当天商城消费订单信息
*/
@Service("orderStatisticsOperator")
//@Service("orderStatisticsInterface")
@Transactional
//public class OrderStatisticsOperator implements OrderStatisticsInterface{
public class OrderStatisticsOperator{
@Autowired
private OrderStatisticsPartMapper orderStatisticsPartMapper;
// @Override
public List<OrderStatisticsPart> selectOrdersInfoByToday(String today_date) {
return orderStatisticsPartMapper.selectOrdersInfoByToday(today_date);
}
}
4.ApplicationContextUtil类,要注意在以前博客上的代码中是没有@Component的!!!!!!
package service.timer; import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller; /**
* @author zyr
* 由于定时器的执行优先于注入,因此我们不能通过@Resource注入service
* 因此需要创建一个类ApplicationContextUtil,用来获取service
*/
@Component
public class ApplicationContextUtil implements ApplicationContextAware{
private static ApplicationContext applicationContext;
private static Logger logger = Logger.getLogger(ApplicationContextUtil.class); public static ApplicationContext getApplicationContext() {
return applicationContext;
} public void setApplicationContext(ApplicationContext applicationContext) {
logger.debug("------SpringContextUtil setApplicationContext-------");
ApplicationContextUtil.applicationContext = applicationContext;
}
public static Object getBean(String beanName)
{
return applicationContext.getBean(beanName);
}
}
如果我之前看到该多好呀,可惜是一天之后了,下面我来给大家说一下我看到这个错误做了什么事情!!!
首先我在网上搜索了这个问题,还真的让我给找到了一个同样的问题,就是这篇“该死的博客”让我一直苦逼不堪!!!!!!
http://blog.csdn.net/u011277123/article/details/54285896
根据这篇博客上说的,我发现这就是我的翻版呀,哈哈,然后我开开心心的起了个大早就来搞这个东西了,结果这个博客上有一点不清楚的地方,那就是@Service("一些名称"),括号中的东西到底应该是什么,当然可以是任意字符串,那意思呢,因为我当时直接在OrderStatisticsOperator中直接写了@Service("orderStatisticsOperator")这样的东西,并且在定时器中,使用:
OrderStatisticsOperator orderStatisticsOperator=(OrderStatisticsOperator)ApplicationContextUtil.getBean("orderStatisticsOperator");
来直接运行,结果就错了,错了,当然了,在以前的博客上是没有@Component的,因此报的错一直是空指针错误,让我们看一下这个语句,一直报错,这浪费我三个多小时,我一直搞不懂这个东西为什么会报错,而且是空指针错误,因为程序一直卡在ApplicationContextUtil.getBean("orderStatisticsOperator");这个语句上面,提示这个语句空指针错误,我在想是不是beanName中传进的参数orderStatisticsOperator的错,可是也没错呀,如果是全称的话也可以的,但是我已经在@Service中表明了这个名字,应该没错的,那是怎么回事呢,想呀想,改不成是applicationContext的错吧,因为applicationContext.getBean(beanName);,如果applicationContext为空,那么将会是null..getBean(beanName);那么肯定会是空指针异常了,这让我绝望,因为我们的这个类是继承自ApplicationContextAware的,这个东西里面我们重载了 getBean(String beanName)方法和setApplicationContext(ApplicationContext applicationContext) 方法,也就是说在程序运行的时候,加载的过程中就会调用setApplicationContext对我们的applicationContext赋值了,这个意思是应用上下文,当然是在这个时候就给我们的了,可是还是出错,到底是怎么回事呢,我把这个文件放到了controller层还是不行,因为我在另一篇博客上看到,这个定时任务是Spring的,而不是Springmvc上面的应该,而前者比后者先初始化,也就是说前者是后者的父亲,Springmvc是Spring的孩子,应该现在父亲那边初始化才能因为继承的关系在Springmvc中有效,可是放到了controller中还是没用呀,真的坑。。。于是我又进行了一些细微的修改还是不行
public static Object getBean(String beanName)
{
return applicationContext.getBean(beanName);
}
就在我快要绝望的时候,突然想起来,我们把这个自己定义的类当做bean,却没有能够让框架扫描到这个东西,因为没有暴露任何东西,所以我在这个类的前面加了个@Component,也就是在这个时候奇迹出现了,程序总算不在报空指针错误了,原来自己之前的所有操作都是因为没有加这个东西,不能让框架扫描到,当然是不能调用里面重载的setApplicationContext方法,从而applicationContext就是空null的,按理说这样总算是解决了问题了,我又运行一下程序,谁知道还是在报以前的错误,mybatis解析不了,我的天呀,当时我的心态真的是爆炸了,想的是原来这个东西,我搞了这么长时间,总算把bean注入到了我需要的地方了,却没有任何效果,就在我痛定思痛的时候,我想到了是不是因为我的那个mapper.xml真的有问题呢,因为以前就有这样的问题,后来我仔细一看还真是有问题,就是少了一个‘s’,我的天,我的世界电闪雷鸣了,赶紧改过来再运行一下,结果正常了,正常了,正常了!!!!!!后来我在想既然用了这个新的类我的程序正常了,并且这个时候我还实现了一个operator的接口,这是我从其他博客中学到的,接口如下:
package service.statistics;
import java.util.List; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import pojo.part.OrderStatisticsPart;
import mapper.part.OrderStatisticsPartMapper; /**
* @author zyr
* 按日期查询当天商城消费订单信息
*/
public interface OrderStatisticsInterface { public List<OrderStatisticsPart> selectOrdersInfoByToday(String today_date);
}
调用的方法如下:
OrderStatisticsInterface orderStatisticsInterface=(OrderStatisticsInterface)ApplicationContextUtil.getBean("orderStatisticsInterface");
这样是正常的,那么我不用接口呢?也就是:
OrderStatisticsOperator orderStatisticsOperator=(OrderStatisticsOperator)ApplicationContextUtil.getBean("orderStatisticsOperator");
我试了一下,把一些相应的地方改了一下,竟然也正常了,我哭。。。。
后来想了一下干脆不用这个类,我试一下怎么样,我当时想的是肯定是不行的,谁知道呀,竟然可以了,可以了。。。
也就是这样做,竟然成功了,和我以前编程的方法一模一样,真的是让人难以接受呀!!!!!!原来自己搞了一天的时间就是因为一个字母,只是一个字符呀,都不是字符串,哇哇~~~
@Component
public class StatisticsTimer {
@Autowired
private OrderStatisticsOperator orderStatisticsOperator;
private static Logger logger = Logger.getLogger(StatisticsTimer.class);
//一次性查询所有的订单相关信息
private List<OrderStatisticsPart> orderStatisticsList = new ArrayList<OrderStatisticsPart>();
//定时器测试
@Scheduled(cron="0/20 * * * * ? ")
// @Scheduled(cron="0 59 23 ? * *")
public void statisticsTimerCycle(){
System.out.println("============begining===============");
//按时间查询该天商城的所用订单,返回订单的中需要用到的字段,实现统计功能
// OrderStatisticsOperator orderStatisticsOperator=(OrderStatisticsOperator)ApplicationContextUtil.getBean("orderStatisticsOperator");
// ApplicationContext appCtx = ApplicationContextUtil.getApplicationContext();
// logger.debug(appCtx);
// if(appCtx==null)
// {
// logger.debug("ApplicationContext 为空");
// }
// OrderStatisticsOperator orderStatisticsOperator=(OrderStatisticsOperator)ApplicationContextUtil.getBean("orderStatisticsOperator");
//
// OrderStatisticsInterface orderStatisticsInterface=(OrderStatisticsInterface)ApplicationContextUtil.getBean("orderStatisticsInterface");
System.out.println(orderStatisticsOperator);
System.out.println("===========暂无问题===============");
orderStatisticsList= orderStatisticsOperator.selectOrdersInfoByToday(DateTimeTool.get_now_date());
System.out.println("============end===============");
// //当前销售菜品统计
// dishStatisticsTask();
// //当前商家销售情况统计
// shopStatisticsTask();
// //当前商家等位时间统计
// waitingTimeStatisticsTask();
}
到了这一步,我可以看到,首先是在网上找的那个程序有问题,没有在类的前面加上@Component,加上了之后使用这个方法也是可以的;
其次,就是无论实现不实现接口和类,其实都是可以的,不一定非要用接口;
最后就是我的程序最本质的错误是在mapper.xml上,这个东西真的坑,以后一定要加倍小心,特别是刚才那种错误,真的是难以发现呀!!!!!!
因此我觉得.xml真的是一个让程序员又爱又恨的东西,爱的原因是这种文件为程序员节约了大量的时间,想要什么功能只要简单的配置就好了,甚至可以灵活地改变自己需要的东西,实现不同的功能,剩下的就交给web容器去解决了,这点来说真的是神器,可是与之相对应的就是对于一些出错信息缺少智能提示的问题,要知道一个好的开发环境是能够让程序员快速而准确地定位自己的错误,并且找到相应的解决办法的,而这个.xml文件对于“”里面的东西是没有解析能力的,只能够处理最基本的语法,比如结构不对称等,这显示是低级的,从可能性的角度来说,.xml在以后还是可能走向越来越智能的道路的,只不过框架这样做的话效率会下降吧,就如我之前说的这个错误,有的时候是在所难免的,人非圣贤,孰能无过,只不过错了却不一定会往这方面想呀,再加上myeclipse报的错误往往有误导的作用,特别是.xml文件出错的情况下,基本上都是没有参考价值的,正如我上一次在.xml中对于一个参数类型的描述,本来是jdbcType=VARCHAR的,而我写成了,jdbcType=String,结果给我报的错误,那是真的让人绝望呀,最后找了好久才找到,大大的浪费了开发的时间,就像这个错误浪费了我一天的时间一样,那个错误也整整浪费了我的大半天,与其他开发工具相比,我还是觉得java需要在这个方面改进一下,让.xml更加的智能起来,这样才能成为大家更喜爱的开发软件。当然了在我的这个错误中,使用网上说的那个方法也是可以的,但是一定要注意一些细节。下面,我对这几种方法进行梳理:
方法一:使用原生的方法,直接依赖注入。
1.1、OrderStatisticsPartMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.part.OrderStatisticsPartMapper"> <resultMap id="order_statistics_part" type="pojo.part.OrderStatisticsPart">
<result column="order_id" jdbcType="VARCHAR" property="orderId" />
<result column="shop_account_id" jdbcType="INTEGER" property="shopAccountId" />
<result column="wating_start_time" jdbcType="VARCHAR" property="watingStartTime" />
<result column="waiting_end_time" jdbcType="VARCHAR" property="waitingEndTime" />
<result column="pay_total_price" jdbcType="DECIMAL" property="payTotalPrice" />
</resultMap> <select id="selectOrdersInfoByToday" resultMap="order_statistics_part">
select order_id ,shop_account_id , wating_start_time , waiting_end_time , pay_total_price
from orders </select> </mapper>
1.2、OrderStatisticsPartMapper接口
package mapper.part; import java.util.List; import org.apache.ibatis.annotations.Param;
import org.mybatis.spring.annotation.MapperScan; import pojo.part.OrderStatisticsPart; /**
* @author zyr
* 查询当天该商城产生的所有订单信息
* 并返回信息需要的字段
*/
public interface OrderStatisticsPartMapper {
List<OrderStatisticsPart> selectOrdersInfoByToday(@Param("today_date")String today_date);
}
1.3.OrderStatisticsOperator:service层,其实也可以不用,直接在定时器中调用mapper
package service.statistics;
import java.util.List; import javax.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import pojo.part.OrderStatisticsPart;
import mapper.part.OrderStatisticsPartMapper; /**
* @author zyr
* 按日期查询当天商城消费订单信息
*/
@Service public class OrderStatisticsOperator{
@Autowired
private OrderStatisticsPartMapper orderStatisticsPartMapper; public List<OrderStatisticsPart> selectOrdersInfoByToday(String today_date) {
return orderStatisticsPartMapper.selectOrdersInfoByToday(today_date);
}
}
1.4.定时器任务类:StatisticsTimer
package service.timer;
import java.util.ArrayList;
import java.util.List; import mapper.DishSaleStatisticsMapper;
import mapper.part.OrderStatisticsPartMapper; import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service; import pojo.part.OrderDetailStatisticsPart;
import pojo.part.OrderStatisticsPart;
import service.statistics.DishSaleStatisticsOperator;
import service.statistics.OrderDetailStatisticsOperator;
import service.statistics.OrderStatisticsInterface;
import service.statistics.OrderStatisticsOperator;
import service.statistics.ShopSaleStatisticsOperator;
import service.statistics.WaitingTimeStatisticsOperator;
import tools.time.DateTimeTool; /**
* @author zyr
* 系统定时器,每一天定时运行一次,进行统计工作
*/
@Component
public class StatisticsTimer {
@Autowired
private OrderStatisticsOperator orderStatisticsOperator;
private static Logger logger = Logger.getLogger(StatisticsTimer.class);
//一次性查询所有的订单相关信息
private List<OrderStatisticsPart> orderStatisticsList = new ArrayList<OrderStatisticsPart>();
//定时器测试
@Scheduled(cron="0/20 * * * * ? ")
public void statisticsTimerCycle(){
System.out.println("============begining===============");
//按时间查询该天商城的所用订单,返回订单的中需要用到的字段,实现统计功能 System.out.println(orderStatisticsOperator);
System.out.println("===========暂无问题===============");
orderStatisticsList= orderStatisticsOperator.selectOrdersInfoByToday(DateTimeTool.get_now_date());
System.out.println("============end===============");
}
}
就这样一个程序就可以正常工作了,当然定时器要有之前的配置,这里不再赘述。
方法二:使用ApplicationContextUtil,继承ApplicationContextAware,并且不创建新的服务层接口
首先,方法一中的OrderStatisticsPartMapper.xml和OrderStatisticsPartMapper接口都没变。
其次在以前的服务中作如下修改:
package service.statistics;
import java.util.List; import javax.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import pojo.part.OrderStatisticsPart;
import mapper.part.OrderStatisticsPartMapper; /**
* @author zyr
* 按日期查询当天商城消费订单信息
*/
@Service("orderStatisticsOperator")
public class OrderStatisticsOperator{
@Autowired
private OrderStatisticsPartMapper orderStatisticsPartMapper;
public List<OrderStatisticsPart> selectOrdersInfoByToday(String today_date) {
return orderStatisticsPartMapper.selectOrdersInfoByToday(today_date);
}
}
并且增加一个新的类:ApplicationContextUtil,注意红色的部分!!!!!!
package service.timer; import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller; /**
* @author zyr
* 由于定时器的执行优先于注入,因此我们不能通过@Resource注入service
* 因此需要创建一个类ApplicationContextUtil,用来获取service
* 但是经过测试,事实并非如此,与版本有关
*/
@Component
public class ApplicationContextUtil implements ApplicationContextAware{
private static ApplicationContext applicationContext;
private static Logger logger = Logger.getLogger(ApplicationContextUtil.class); public static ApplicationContext getApplicationContext() {
return applicationContext;
} public void setApplicationContext(ApplicationContext applicationContext) {
logger.debug("------SpringContextUtil setApplicationContext-------");
ApplicationContextUtil.applicationContext = applicationContext;
}
public static Object getBean(String beanName)
{
return applicationContext.getBean(beanName);
}
}
然后在定时器中:其中注释的部分也可以打开,看看对象是否为空,肯定不空!一定要注意@Component!!!!!!
/**
* @author zyr
* 系统定时器,每一天定时运行一次,进行统计工作
*/
@Component
public class StatisticsTimer {
private static Logger logger = Logger.getLogger(StatisticsTimer.class);
//一次性查询所有的订单相关信息
private List<OrderStatisticsPart> orderStatisticsList = new ArrayList<OrderStatisticsPart>();
//定时器测试
@Scheduled(cron="0/20 * * * * ? ")
public void statisticsTimerCycle(){
System.out.println("============begining===============");
//按时间查询该天商城的所用订单,返回订单的中需要用到的字段,实现统计功能
OrderStatisticsOperator orderStatisticsOperator=(OrderStatisticsOperator)ApplicationContextUtil.getBean("orderStatisticsOperator");
// ApplicationContext appCtx = ApplicationContextUtil.getApplicationContext();
// logger.debug(appCtx);
// if(appCtx==null)
// {
// logger.debug("ApplicationContext 为空");
// } System.out.println(orderStatisticsOperator);
System.out.println("===========暂无问题===============");
orderStatisticsList= orderStatisticsOperator.selectOrdersInfoByToday(DateTimeTool.get_now_date());
System.out.println("============end===============");
}
之后运行:
方法三:使用ApplicationContextUtil,继承ApplicationContextAware,并且创建新的服务层接口
这个时候,需要再创建一个新的接口:OrderStatisticsInterface
package service.statistics;
import java.util.List; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import pojo.part.OrderStatisticsPart;
import mapper.part.OrderStatisticsPartMapper; /**
* @author zyr
* 按日期查询当天商城消费订单信息
*/
public interface OrderStatisticsInterface { public List<OrderStatisticsPart> selectOrdersInfoByToday(String today_date);
}
然后在刚刚的service中继承该接口:
package service.timer;
import java.util.ArrayList;
import java.util.List; import mapper.DishSaleStatisticsMapper;
import mapper.part.OrderStatisticsPartMapper; import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service; import pojo.part.OrderDetailStatisticsPart;
import pojo.part.OrderStatisticsPart;
import service.statistics.DishSaleStatisticsOperator;
import service.statistics.OrderDetailStatisticsOperator;
import service.statistics.OrderStatisticsInterface;
import service.statistics.OrderStatisticsOperator;
import service.statistics.ShopSaleStatisticsOperator;
import service.statistics.WaitingTimeStatisticsOperator;
import tools.time.DateTimeTool; package service.statistics;
import java.util.List; import javax.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import pojo.part.OrderStatisticsPart;
import mapper.part.OrderStatisticsPartMapper; /**
* @author zyr
* 按日期查询当天商城消费订单信息
*/
@Service("orderStatisticsInterface")
public class OrderStatisticsOperator implements OrderStatisticsInterface{
@Autowired
private OrderStatisticsPartMapper orderStatisticsPartMapper;
@Override
public List<OrderStatisticsPart> selectOrdersInfoByToday(String today_date) {
return orderStatisticsPartMapper.selectOrdersInfoByToday(today_date);
}
}
最后在timer中:
where pay_time like '#{today_date,jdbcType = VARCHAR}%' package service.timer;
import java.util.ArrayList;
import java.util.List; import mapper.DishSaleStatisticsMapper;
import mapper.part.OrderStatisticsPartMapper; import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service; import pojo.part.OrderDetailStatisticsPart;
import pojo.part.OrderStatisticsPart;
import service.statistics.DishSaleStatisticsOperator;
import service.statistics.OrderDetailStatisticsOperator;
import service.statistics.OrderStatisticsInterface;
import service.statistics.OrderStatisticsOperator;
import service.statistics.ShopSaleStatisticsOperator;
import service.statistics.WaitingTimeStatisticsOperator;
import tools.time.DateTimeTool; /**
* @author zyr
* 系统定时器,每一天定时运行一次,进行统计工作
*/
@Component
public class StatisticsTimer {
private static Logger logger = Logger.getLogger(StatisticsTimer.class);
//一次性查询所有的订单相关信息
private List<OrderStatisticsPart> orderStatisticsList = new ArrayList<OrderStatisticsPart>();
//定时器测试
@Scheduled(cron="0/20 * * * * ? ")
public void statisticsTimerCycle(){
System.out.println("============begining===============");
//按时间查询该天商城的所用订单,返回订单的中需要用到的字段,实现统计功能
ApplicationContext appCtx = ApplicationContextUtil.getApplicationContext();
logger.debug(appCtx);
if(appCtx==null)
{
logger.debug("ApplicationContext 为空");
}
OrderStatisticsInterface orderStatisticsInterface=(OrderStatisticsInterface)ApplicationContextUtil.getBean("orderStatisticsInterface");
System.out.println(orderStatisticsInterface);
System.out.println("===========暂无问题===============");
orderStatisticsList= orderStatisticsInterface.selectOrdersInfoByToday(DateTimeTool.get_now_date());
System.out.println("============end===============");
}
结果为:
综上所述,这就是我这一天多完成的任务了,虽然遇到了困难,并且放大了困难,也确实学到了一些好的方法,算是为自己对springmvc和Spring的理解创造了条件,奠定了坚实的基础,对于组件扫描,以及定时器的操作有了更深刻的认识,希望能对读者有意义,帮助大家解决一定的问题,可以看到我陈述解决问题的时候,非常的细腻,不漏过任何的东西,这也是很多博客做不到的,只专注于一件事情,并且做到最好,让大家可以照着做一遍,而不是一知半解!
又是一个愚蠢的错误,皆因.xml而起的更多相关文章
- 一个愚蠢的python逻辑语法错误
这个事情再次佐证了一个莫名其妙的现象背后一定会有一个愚蠢到无以复加的错误的真理. 写python单元测试的时候发现一个莫名其妙的问题: def xmlStandander(self,s): retur ...
- InnerException 消息是“反序列化对象 属于类型 *** 时出现错误。读取 XML 数据时,超出最大字符串内容长度配额 (8192)。(注意细节)
WEB站点在调用我们WCF服务的时候,只要传入的参数过长,就报如下错误: 格式化程序尝试对消息反序列化时引发异常: 尝试对参数 http://tempuri.org/ 进行反序列化时出错: formD ...
- 在JavaScript种遇到这样的错误如何解决XML 解析错误:格式不佳 位置:http:/... 行 27,列 32:
相信很多人在开发的过程中都会遇到在js中解析xml文档的问题.有时候文档解析失败,但就是不知道怎么失败的,哪里格式不对.这里教大家一个方法来排查JavaScript解析xml文档格式出错的办法. 1. ...
- tomcat下部署两个工程时,只有一个可以访问,另一个出现404错误,该如何解决
tomcat下部署两个工程时,只有一个可以访问,另一个出现404错误,该如何解决 在开发新项目的时候,有时候为了省时,直接把曾经做过的项目工程A拷贝成改名为B工程,然后再在B工程上进行功能的开发, 此 ...
- 关于启动 SecureCRT 遇到一个致命的错误且必须关闭
--------------------------SecureCRT---------------------------SecureCRT 遇到一个致命的错误且必须关闭. 一个崩溃转储文件已创建于 ...
- Windows下一个MySQL有些错误的解决方法
1.无论是什么提示.我们有一个直接看错误日志.由于它描述了最具体描述错误日志. 于MySQL安装文件夹中找到 my.ini简介 看日志保存路径 2. 我的错误是[ERROR] Fatal error: ...
- “SecureCRT遇到一个致命的错误且必须关闭”处理办法
打开SecureCRT时报错:SecureCRT遇到一个致命的错误且发须关闭.一个崩溃转储文件已创建于... 解决办法是,如下在cmd中输入regedit回车打开注册表编缉器 展开HKEY_LOCAL ...
- 记录一次错误处理 (xml序列化和反序列化相关)
XML序列化后,反序列化时出现错误 报错现象 System.InvalidOperationException: XML 文档(40, 11)中有错误. ---> System.Xml.XmlE ...
- 个人犯的一个golang routine错误
这个其实不是错误,2个写法没有区别.-2015.11.22 认识golang也不少时间了,也做过几个项目.最近发现之前用golang写的一个服务,内存涨得比较快,一直没找出来原因来.今天把疑惑发到群里 ...
随机推荐
- linux_操作系统
如何查询操作系统版本? cat /etc/redhat-release 什么是操作系统? -- win10,linux都是os,应用软件和硬件打交道中间桥梁软件,管理 硬件+软件 资源,计算机系统基础 ...
- java里程碑之泛型--擦除和转换
在严格的泛型代码里,带泛型声明的类总应该带着泛型参数.但是为了和古老的java代码保持一致,也就是说为了向下兼容,也允许在使用带泛型声明的类时不指定实际的类型参数.如果没有为这个泛型类指定实际的参数类 ...
- linkin大话设计模式--常用模式总结
linkin大话设计模式--常用模式总结 一,常用设计模式定义 Abstract Factory(抽象工厂模式):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. Adapter( ...
- Selenium+java+idea的安装与配置
当前操作系统:Windows10pro x64 一.安装JDK 1.到jdk官网下载一个对应当前系统的安装包(Selenium仅支持JDK1.8及以上版本) 网址:http://www.oracle. ...
- js中常用的方法(数组篇)
1.replace(),根据释义,即为代替,用法为: stringObject.replace(regexp/substr,replacement)括号内前者是待匹配字符串,并用后者代替这个字符串.例 ...
- Windows--查看使用某端口的进程
场景: 有时候我们希望查找某个端口被那个进程使用,如何操作呢? 比如查找8000端口被按个进程使用? 首先使用netstat -ano |grep 8000查看 13776就是使用的进程ID 然后使用 ...
- HH的项链
传送门 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的贝壳,因此,他的项链变得越 ...
- 关于if和else嵌套—蛋疼
嵌套使用的时候else if和else遵循就近原则,和上面最靠近该语句的if语句匹配,要把else if看成是一个整体.就这么干,这样好理解一点. 一个if...else if...else语句中可以 ...
- 模块dll和lib
一.dll动态链接库 1.dll 没有 main 函数 2.不能直接执行,可以注入exe中让它间接执行.只有把它编译到应用程序中才可以. 3.编写dll 函数前加上 _declspec(dllexpo ...
- jmeter用Firefox录制https协议证书问题解决
录制脚本的时候,比如录制https协议的百度网站 https://www.baidu.com ,所有录制设置均正常,但是在jmeter录制控制器里面就是没有任何录制的请求. 这个时候提示说证书不对 1 ...