回调机制运用什么场景?
1、当你正在做事,但有个信息需要别人通知你,那个人很忙说你留个电话我,有消息我就通知你,你继续干你的事,两不误。可以解决阻塞问题。
2、在某个条件满足后去执行未知的逻辑,因为未知,所以预留接口待外界传入类,有点模板方法的意思。这个可以解耦。
写一个例子:
场景:某员工正在拍卖现场出价,老板说:你按我的指示出价,如果我有变动会通知你,你再改变出价。
分析:员工要不停的出价,不能因为等待老板的电话而停止出价。我们将员工实现callback接口,注入另外个线程,当老板有电话时将信息传入员工,这样不会影响员工工作。
代码:
package my.test.callback;
/**
*
* 描述 回调接口
*
* @author 锅巴
* @version 1.0 2010-10-15
*/
public interface IMessageCallBack {
void receiveMessage(String message);
}
package my.test.callback;
/**
*
* 描述 员工并实现回调接口
*
* @author 锅巴
* @version 1.0 2010-10-15
*/
public class Employee implements IMessageCallBack{
private int value = 8888;
/**
* 不断的出价
*/
public void doWork(){
while(true){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("value:" + value);
}
}
/**
* 回调方法,接收老板指令
*/
public void receiveMessage(String message) {
// TODO Auto-generated method stub
value = Integer.parseInt(message);
}
}
package my.test.callback;
import java.util.Random;
import org.springframework.beans.factory.InitializingBean;
/**
*
* 消息监听器
*
* @author 锅巴
* @version 1.0 2010-10-15
*/
public class Messagelisten implements InitializingBean{
private IMessageCallBack messageCallBack;
public void init(){
(new Thread(new MessageCreate(messageCallBack))).start();
}
public void setMessageCallBack(IMessageCallBack messageCallBack) {
this.messageCallBack = messageCallBack;
}
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
if(messageCallBack == null){
throw new IllegalAccessException("error: messageCallBack is null");
}
}
}
class MessageCreate implements Runnable{
private IMessageCallBack messageCallBack;
public MessageCreate(IMessageCallBack messageCallBack){
this.messageCallBack = messageCallBack;
}
public void run() {
// TODO Auto-generated method stub
String message = null;
while((message = listen()) != null){
messageCallBack.receiveMessage(message);
}
}
private String listen(){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("---------- listen -----------");
Random random = new Random();
if(random.nextInt(10) > 5){
return String.valueOf(random.nextInt(10000));
}
return null;
}
}
配置文件
<bean id="employee" class="my.test.callback.Employee"/>
<bean id="messagelisten" class="my.test.callback.Messagelisten" init-method="init">
<property name="messageCallBack" ref="employee"/>
</bean>
Test
package my.test.user.api;
import my.test.callback.Employee;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CallBackTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("callback.context.xml");
Employee employee = (Employee)context.getBean("employee");
employee.doWork();
}
}