callback 回调
来源:互联网 发布:数据采集板卡 编辑:程序博客网 时间:2024/06/06 00:38
前段时间看Spring的源码,看到HibernateTemplate里的HibernateCallback(),实在有不明白,于是在网上找了些文章和代码,
自己也试着写了些代码,由于是半路出家,才疏学浅,太理论的东西说不上来,只有靠代码说明问题。如有不对的地方还请高手指教。
一、初步理解
先看看比较流行的老板、工人和工作汇报的例子
/**
*
*报告接口
*/
public interface Report{
public String workReport();
}
/**
*
* 工作报告
*/
public class ReportImpl implements Report{
/**
* 返回要报告的工作信息
*
* @return 报告工作信息
*/
public String workReport() {
return "工作汇报 Report";
}
}
/**
*
* 工人
*/
public class Worker{
private String name; //工人姓名
private Boss boss; //工人所属的老板
public Worker(String name, Boss boss) {
this.name = name;
this.boss = boss;
}
public String getName() {
return name;
}
/**
* 开工
* @param event 事件
*/
public void doWork(Report report){
System.out.println(name + ":开工大吉");
for(int i=0; i<20000; i++){
}
System.out.println(name + ": 搞定~!");
System.out.println(name + ": 向老板报告工作");
boss.workerReport(this, report);
}
}
/**
*
* 老板
*/
public class Boss {
/**
* 老板接收工人的工作汇报
* @param worker 工人
* @param report 报告
*/
public void workerReport(Worker worker, Report report){
System.out.println("老板收到工人 " + worker.getName() + " 的工作报告: " + report.workReport());
}
}
/**
*
* 测试类
*/
public class Test {
public static void main(String args[]){
Boss boss = new Boss();
Worker worker1 = new Worker("小盖",boss);
Worker worker2 = new Worker("老巴",boss);
Report reportA = new ReportImpl();
Report reportB = new ReportImpl();
worker1.doWork(reportA);
worker2.doWork(reportB);
}
}
输出结果
小盖:开工大吉
小盖: 搞定~!
小盖: 向老板报告工作
老板收到工人 小盖 的工作报告: 工作汇报 Report
老巴:开工大吉
老巴: 搞定~!
老巴: 向老板报告工作
老板收到工人 老巴 的工作报告: 工作汇报 Report
二、OK,让我们看看还有什么改进
看到上边的代码应该有点感觉了吧,但还是有可以改进的余地。
看看Boss类,Boss要见到Worker才知道workReport是谁的。
其实Boss不用知道有哪些Worker来他那里汇报过工作,只要看Report就可以了。
那我们修改一下Boss类和Worker类。
/**
*
* 老板
*/
public class Boss {
/**
* 老板接收工人的工作汇报
* @param report 报告
*/
public void workerReport(Report report){
System.out.println("老板收到工人的工作报告: " + report.workReport());
}
}
/**
*
* 工人
*/
public class Worker{
private String name; //工人姓名
private Boss boss; //工人所属的老板
public Worker(String name, Boss boss) {
this.name = name;
this.boss = boss;
}
public String getName() {
return name;
}
/**
* 开工
* @param event 事件
*/
public void doWork(){
System.out.println(name + ":开工大吉");
for(int i=0; i<20000; i++){
}
System.out.println(name + ": 搞定~!");
System.out.println(name + ": 向老板报告工作");
//匿名内部类
boss.workerReport(
new Report(){
public String workerReport(){
return name + "的工作汇报 Report";
}
}
);
}
}
ReportImpl类!?这时可以不要了。
/**
*
* 测试类
*/
public class Test {
public static void main(String args[]){
Boss boss = new Boss();
Worker worker1 = new Worker("小盖",boss);
Worker worker2 = new Worker("老巴",boss);
//这里不用再new Report了,这些让Worker自己去做
worker1.doWork();
worker2.doWork();
}
}
输出结果和上边一样。我们可以看到匿名内部类的好处,是不用将Worker的实例传入到Report的实现类中。
三、看看Spring做了些什么
(Spring 2.5)
org.springframework.orm.hibernate3.HibernateTemplate
...
public Serializable save(final Object entity) throws DataAccessException {
return (Serializable) executeWithNativeSession(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session);
return session.save(entity);
}
});
}
...
public Object executeWithNativeSession(HibernateCallback action) {
return doExecute(action, false, true);
}
...
protected Object doExecute(HibernateCallback action, boolean enforceNewSession, boolean enforceNativeSession)
throws DataAccessException {
...
}
...
现在让我们模仿Spring写一个回调的练习代码
为了将注意力放到练习上,而不被Spring如何获得Session扰乱,所以写个MySession类,并且用String代替了传入的实例。
/**
*
* 练习类
*/
public class MySession {
/**
* @param obj
*/
//用String代理了Object
public String save(String obj){
return "MySession.save " + obj;
}
/**
* @param obj
*/
public String pudate(String obj){
return "MySession.pudate " + obj;
}
...
}
/**
* Callback接口
* 相当于HibernateCallback接口
*/
public interface HCallback {
public String doInCallback(MySession session);
}
/**
* HTemplate类
* 相当于HibernateTemplate类
*/
public class HTemplate {
/**
* @param user
*/
//用String代理了Object类
public String save(final String object){
System.out.println(object + ":我在 HTemplate的save 方法中");
return executeWithNativeSession(
new HCallback(){
public String doInCallback(MySession session){
System.out.println(object + ":我在 HCallback的doInCallback 方法中");
return session.save(object);
}
}
);
}
...
/**
* @param hcallback 回调接口
*/
public String executeWithNativeSession(HCallback hcallback){
//由于不关心Spring中如何获得Session,所以练习代码中这里new了一个 MySession 实例
MySession session = new MySession();
return hcallback.doInCallback(session);
}
}
/**
* HDaoSupport
* 相当于HibernateDaoSupport
*/
public class HDaoSupport {
public HDaoSupport(){
}
public HTemplate getHTemplate() {
return new HTemplate();
}
}
/**
* DaoImpl类
*
*/
public class UserDaoImpl extends HiDaoSupport implements UserDao {
/**
* @param user
*/
public String add(String user) {
return this.getHTemplate().save(user);
}
...
}
/**
*
* 测试类
*/
public class Test {
public static void main(String args[]){
UserDao userDao = new UserDaoImpl();
String result = userDao.add("小贝");
System.out.println(result);
}
}
输出结果
小贝:我在 HTemplate的save 方法中
小贝:我在 HCallback的doInCallback 方法中
MySession.save 小贝
四、在Hibernate的项目中完成自己的回调
当项目中没有用到Spring时,那可以模仿写一个
/**
* 回调接口
*
*/
public interface HibernateCallback {
public Object execute(Session session) throws HibernateException;
}
/**
* 模板类
*
*/
public class HibernateTemplate {
public static Object run(HibernateCallback callback) throws HibernateException {
Session session = null;
Transaction tx = null;
try{
session = HibernateSessionFactory.getCurrentSession();
tx = seesion.beginTransaction();
//留意这里
Object result = callback.execute(session);
tx.commit();
return result;
} catch(HibernateException e){
tx.rollback();
return null;
}
}
}
/**
*
* HibernateSupport类
*/
public class HibernateSupport {
public Object save(final Object object) throws HibernateException{
//回调
return HibernateTemplate.run(
new HibernateCallback(){
public Object execute(Session session) throws HibernateException{
return session.save(object);
}
}
);
}
...
//其他方法
}
/**
*
* DaoSupport类
*/
public class DaoSupport {
public DaoSupport(){
}
public HibernateSupport getHibernateSupport() throws HibernateException {
return new HibernateSupport();
}
}
/**
*
* Dao类
*/
public class UserDaoImpl extends DaoSupport implements UserDao{
public void save(User user) throws HibernateException{
this.getHibernateSupport().save(user);
}
}
以上代码参考
http://lavasoft.blog.51cto.com/62575/90453
http://hi.baidu.com/johnsoncr/blog/item/2a782f4b592681f582025c13.html
感谢他们的分享
- CallBack回调
- callback 回调
- callback 回调
- 认识callback(回调)
- JS 回调(CallBack)
- JS 回调(CallBack)
- JS 回调(CallBack)
- 小测试-Callback-回调
- JS 回调(CallBack)
- 回调Callback之Java
- js 回调(callback)
- 回调(callback)
- Java-回调(Callback)
- 回调(callback)机制
- CALLBACK
- callback
- Callback
- CALLBACK
- WinXP无法关机?
- .net网站发布只生成一个dll的方法
- JS得到窗口高度
- SCJP十二
- SCJP十三
- callback 回调
- 6年软件开发工作总结
- 支持韩允熙的朋友,那就请大家帮忙发帖子吧
- C语言下的清屏函数
- 谁知道怎么优化这个SQL语句?
- C#中控件的缩写大全
- Linux字符设备驱动程序开发
- masm中关于SEH的宏
- linux中用shell获取昨天、明天或多天前的日期