精华内容
下载资源
问答
  • java事件驱动
    千次阅读
    2022-01-20 22:35:33

    之前简单写过一些关于事件驱动的文章:【C/C++服务器开发】事件驱动、事件驱动架构、事件驱动编程及设计模式

    最近看到一篇不错的文章,在此转载一下:事件驱动和消息驱动

    事件驱动和消息驱动
    消息驱动和事件驱动很类似,都是先有一个事件,然后产生一个相应的消息,再把消息放入消息队列,由需要的项目获取。他们的区别是消息是谁产生的

    消息驱动:鼠标管自己点击不需要和系统有过多的交互,消息由系统(第三方)循环检测,来捕获并放入消息队列。消息对于点击事件来说是被动产生的,高内聚。

    事件驱动:鼠标点击产生点击事件后要向系统发送消息 “我点击了” 的消息,消息是主动产生的。再发送到消息队列中。事件往往会将事件源包装起来。

    事件驱动往往和轮询机制相关,它们通常被统称为 event loop。重点在于并不会给每一个事件分配一个轮询来探知其变化,而是设置一个中央轮询中心,用这个轮询中心去轮询每个注册的对象。轮询中心一旦检测到了注册其中的对象有事件发生,那么就通知对此事件感兴趣的对象。而对此事件感兴趣的对象此时会调用的方法被称为回调函数。

    有时也把事件驱动按照实现方式的不同进行区分(个人并不认为很准确,但是很多人都这么说):

    • 轮询方式
      线程不断轮询访问相关事件发生源有没有发生事件,有发生事件就调用事件处理逻辑。
      事件驱动方式
    • 事件发生时主线程把事件放入事件队列,在另外线程不断循环消费事件列表中的事件,调用事件对应的处理逻辑处理事件。事件驱动方式也被称为消息通知方式,其实是设计模式中观察者模式的思路。
      事件驱动模型可以用下图表示(来源于《Software Architecture Patterns》):

    在这里插入图片描述

    主要包括 4 个基本组件:

    事件队列(event queue):接收事件的入口,存储待处理事件
    分发器(event mediator):将不同的事件分发到不同的业务逻辑单元
    事件通道(event channel):分发器与处理器之间的联系渠道
    事件处理器(event processor):实现业务逻辑,处理完成后会发出事件,触发下一步操作
    比如说在 Java 的 Socket NIO 模型中,SocketChannel 总是将自身注册为对可读、可写事件感兴趣,ServerSocketChannel 却往往将自己注册为对有一个新的 TCP 连接请求感兴趣。不同的类型的对象可以以不同的兴趣注册到同一个分发器中,分发器既需要能够辨别发生了的不同事件,又需要能够将不同的事件分派给不同的事件通道。因为分发器具备这种为有着不同兴趣的不同对象服务的能力,所以分发器仅仅需要占一个线程。

    另一个问题是事件处理器如何知道事件发生了?事件处理器就像人一样,人通过每天时不时地看看报纸、看看手机 APP,”时不时地看“这个动作时由人主动发出的,这是最关键的。处理器需要一个其独享的线程,在这个线程中进行检查是否发生了新的事件,这个线程在没有被通知时是阻塞的,一旦 Event Channel 传来了新的事件,事件处理器就不再阻塞。

    所以,有一个单线程不阻塞地进行轮询事件队列,一旦发现事件发生了,就通过事件分发器,将包装好的事件通过事件通道传给事件处理器。而每个事件处理器也单独占据一个线程,如果此时没有事件传递过来,其就会阻塞,直到事件传递过来。

    事件队列和事件处理器除了在各自的线程模型是否阻塞上有所区别以外,在实现者上也有所区别。通常事件队列包括分发器、事件通道都是由类库替我们完成的,而事件处理器的逻辑则需要更偏向业务的程序员完成。

    更多相关内容
  • 内容索引:Java源码,初学实例,事件驱动 Java事件驱动程序设计相关程序源代码,包括事件事件源、事件的监听、注册和处理、内部类监听器、匿名内部类监听器、处理简单行为的事件、处理窗口事件、监听器接口适配器、...
  • Java事件驱动程序设计相关程序源代码,包括事件事件源、事件的监听、注册和处理、内部类监听器、匿名内部类监听器、处理简单行为的事件、处理窗口事件、监听器接口适配器、鼠标事件、键盘事件、使用Timer类的动画...
  • 收集了一些Java事件驱动编程相关实例源码,都是来自与国外的一些Java代码,里面注释丰富,不过是英文的。这些实例与事件驱动程序设计有关,比如事件监听、注册和处理、内部类监听器、匿名内部类监听器、处理简单行为...
  • Java事件驱动模型框架实现

    千次阅读 2022-04-21 16:50:32
    一、框架实现篇 ... 事件监听器管理类(EventListenerManager):声明一系列的事件监听器,通过@EventAnnotation定义该事件监听器感兴趣的事件类型,最后通过反射的方式实现事件监听器自动注册到Eve.

    一、框架实现篇 

    关键角色

    • 事件源(XXXEvent):能够接收外部事件的源体,内部包含事件的类型。
    • 事件监听器(XXXEventListener):能够接收事件源通知的对象。
    • 事件分发器(EventDispatcher):维护事件类型与事件监听器列表的映射关系,接收事件并进行事件的派发。
    • 事件监听器管理类(EventListenerManager):声明一系列的事件监听器,通过@EventAnnotation定义该事件监听器感兴趣的事件类型,最后通过反射的方式实现事件监听器自动注册到EventDispatcher。

    架构图

    ------------------------------------------------------------------------------------------------------------

    话不多说,直接上代码

    -------------------------------------------------------------------------------------------------------------

    (1)定义事件类型EventType

    package com.example.demo.eventdriven;
    
    /**
     * 
    * @ClassName: EventType
    * @Description: 事件类型
    * @Author: liulianglin
    * @DateTime 2022年4月21日 下午3:35:56
     */
    public enum EventType {
    	LOGIN,//登陆事件
    	EXIT,//退出事件
    	;
    }
    

    (2)定义事件基类BaseEvent

    package com.example.demo.eventdriven;
    
    /**
     * 
    * @ClassName: BaseEvent
    * @Description: 基础事件类
    * @Author: liulianglin
    * @DateTime 2022年4月21日 下午3:34:19
     */
    public class BaseEvent {
    	//是否在消息主线程同步执行
    	private boolean sync = true;
    	
    	//事件类型
    	private final EventType evtType;
    	
    	public BaseEvent (EventType evtType) {
    		this.evtType = evtType;
    	}
    	
    	public BaseEvent (EventType evtType,boolean sync) {
    		this.evtType = evtType;
    		this.sync = sync;
    	}
    
    	public EventType getEvtType() {
    		return evtType;
    	}
    	
    	/**
    	 * 是否在消息主线程同步执行
    	 * @return
    	 */
    	public boolean isSync() {
    		return sync;
    	}
    	
    	public void setSync (boolean sync) {
    		this.sync = sync;
    	}
    }
    

    (3)定义事件监听器接口EventListener

    package com.example.demo.eventdriven;
    
    /**
     * 
    * @ClassName: EventListener
    * @Description: 事件监听接口
    * @Author: liulianglin
    * @DateTime 2022年4月21日 下午3:35:21
     */
    public interface EventListener<E> {
    
    	/**
    	 * 事件触发后,处理具体逻辑
    	 * @param event
    	 */
    	public void handleEvent(E event);
    }
    

    (4)定义事件监听器管理器抽象类AbstractEventListenerManager

    package com.example.demo.eventdriven;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    
    
    /**
     * 
    * @ClassName: AbstractEventListenerManager
    * @Description: 事件监听器管理者基类,通过注解实现事件监听器的自动注册
    * @Author: liulianglin
    * @DateTime 2022年4月21日 下午3:05:43
    * 
    * 将要注册事件的监听器,在 AbstractEventListenerManager 子类属性中,通过注解 @EventAnnotation标记监听器所感兴趣的事件。
    * 详细参见EventListenerManager类
     */
    public abstract class AbstractEventListenerManager {
    	
    	/**
    	 * 初始化 注册监听器(启动程序时调用)
    	 */
    	@SuppressWarnings({ "unchecked" })
    	public void initEventListener () {
    		Field[] fields = getClass().getDeclaredFields();
    		for (Field f:fields) {
    			EventAnnotation evt = f.getAnnotation(EventAnnotation.class);
    			if (evt != null) {
    				EventType eventType = evt.eventType();
    				Class<?> listenClass = f.getType();
    				EventListener<? extends BaseEvent> newInstance;
    				try {
    					newInstance = (EventListener<? extends BaseEvent>)listenClass.getDeclaredConstructor().newInstance();
    					//注册事件
    					EventDispatcher.INSTANCE.registerEvent(eventType, newInstance);
    				} catch (InstantiationException e) {
    					e.printStackTrace();
    				} catch (IllegalAccessException e) {
    					e.printStackTrace();
    				} catch (IllegalArgumentException e) {
    					e.printStackTrace();
    				} catch (InvocationTargetException e) {
    					e.printStackTrace();
    				} catch (NoSuchMethodException e) {
    					e.printStackTrace();
    				} catch (SecurityException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    }
    

    (5)定义一个事件监听器管理器实现EventListenerManager

    package com.example.demo.eventdriven;
    
    import org.springframework.stereotype.Component;
    
    /**
     * 
    * @ClassName: EventListenerManager
    * @Description: 事件监听器管理类
    * @Author: liulianglin
    * @DateTime 2022年4月21日 下午3:08:38
    * 
    * 不同的业务模块可以创建属于自己的EventListenerManager
     */
    @Component
    public class EventListenerManager extends AbstractEventListenerManager {
    
    	/**
    	 * 在构造器中调用父类的initEventListener,完成下方被注解修饰的所有事件监听器自动注册到EventDispatcher
    	 */
    	public EventListenerManager() {
    		super.initEventListener();
    	}
    	
    	/**
    	 * 通过@EventAnnotation定义该事件监听器感兴趣的事件类型
    	 */
    	@EventAnnotation(eventType=EventType.LOGIN)
    	public ExampleEventListener exampleEvent;
    	
    	//这里继续添加其他事件监听器
    	//@Evt(eventType=EventType.EXIT)
    	//public ExampleEventListener exampleEvent2;
    }
    

    这里注意:这里边的ExampleEventListener暂时还没定义,下面使用环节会定义这个类 

    (6)定义一个注解EventAnnotation,用于配合AbstractEventListenerManager实现事件监听器的自动注册

    package com.example.demo.eventdriven;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * 
    * @ClassName: EventAnnotation
    * @Description: 事件注解:指定感兴趣的事件类型
    * @Author: liulianglin
    * @DateTime 2022年4月21日 下午3:32:28
     */
    @Documented
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface EventAnnotation {
    
    	/**事件类型*/
    	public EventType eventType();
    }
    

    (7)再定义一个内部异常类(非必须品)EventDrivenException,用于定义处理内部出现的异常

    package com.example.demo.eventdriven;
    
    /**
     * 
    * @ClassName: EventDrivenException
    * @Description: 事件驱动内部处理异常
    * @Author: liulianglin
    * @DateTime 2022年4月21日 下午3:39:16
     */
    public class EventDrivenException  extends RuntimeException{
    	public EventDrivenException(String message) {
    		super(message);
    	}
    }
    

    (8)事件注册分发中心EventDispatcher

    package com.example.demo.eventdriven;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.LinkedBlockingQueue;
    
    /**
     * 
    * @ClassName: EventDispatcher
    * @Description: 事件分发器
    * @Author: liulianglin
    * @DateTime 2022年4月21日 下午2:57:35
     */
    public enum EventDispatcher {
    	
    	// 采用枚举实现单例模式
    	INSTANCE; 
    	
    	private ExecutorService executorService;
    	
    	// 事件类型与事件处理器列表的映射关系
    	private final Map<EventType,List<EventHandler<? extends BaseEvent>>> observers = new HashMap<>();
    	
    	// 异步执行的事件队列 
    	private LinkedBlockingQueue<BaseEvent> eventQueue = new LinkedBlockingQueue<>();
    	
    	EventDispatcher(){
    		executorService = Executors.newSingleThreadExecutor();
    		executorService.execute(new EventWorker());
    	}
    	
    	/**
    	 * 注册事件
    	 * @param evtType 事件类型
    	 * @param listener 具体监听器
    	 */
    	public void registerEvent(EventType evtType, EventHandler<? extends BaseEvent> listener) {
    		List<EventHandler<? extends BaseEvent>> listeners = observers.get(evtType);
    		if(listeners == null) {
    			listeners = new ArrayList<EventHandler<? extends BaseEvent>>();
    			observers.put(evtType, listeners);
    		}
    		listeners.add(listener);
    	}
    	
    	/**
    	 * 派发事件
    	 * @param event
    	 */
    	public void dispatchEvent(BaseEvent event) {
    		if(event == null) {
    			throw new NullPointerException("the event cannot be null");
    		}
    		
    		if (event.isSync()) {
    			//如果事件是同步的,那么就在消息主线程执行逻辑
    			handler(event);
    		} else {
    			//否则,就丢到事件线程异步执行
    			eventQueue.add(event);
    		}
    		
    	}
    	
    	/**
    	 * 同步处理器
    	 * @param event
    	 */
    	@SuppressWarnings({ "rawtypes", "unchecked" })
    	private void handler (BaseEvent event) {
    		EventType evtType = event.getEvtType();
    		List<EventHandler<? extends BaseEvent>> listeners = observers.get(evtType);
    		if(listeners != null) {
    			// 一个事件可能被多个事件处理器关注及待处理
    			for(EventHandler listener:listeners) {
    				try{
    					listener.handleEvent(event);
    				} catch(Exception e) {
    					//防止其中一个listener报异常而中断其他逻辑
    					e.printStackTrace();  
    				}
    			}
    		}else {
    			throw new EventDrivenException("can not find the event handler with the event type is "+event.getEvtType());
    		}
    	}
    	
    	/**
    	 * 
    	* @Description: 停止异步事件分发线程
    	* @Author: liulianglin
    	* @Datetime: 2022年5月19日 下午7:29:17
    	* @return void
    	* @throws
    	 */
    	public void stopSyncEventDispatchThread () {
    		eventQueue.add(new BaseEvent(EventType.EXIT, false));
    	}
    
    	/**
    	 * 
    	* @ClassName: EventWorker
    	* @Description: 异步执行线程
    	* @Author: liulianglin
    	* @DateTime 2022年4月21日 下午3:43:24
    	 */
    	private class EventWorker implements Runnable {
    
    		@Override
    		public void run() {
    			while (true) {
    				try {
    					BaseEvent event = eventQueue.take();
    					if (event.getEvtType() == EventType.EXIT) {
    						break;
    					}
    					handler(event);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    		
    	}
    }
    

     

    ======================= 至此框架全部代码完毕 =============

    二、框架使用篇

    (1)声明一个业务事件

    package com.example.demo.eventdriven;
    
    
    /**
     * 
    * @ClassName: ExampleEvent
    * @Description: 示例事件(用于演示如何使用该事件驱动框架)
    * @Author: liulianglin
    * @DateTime 2022年4月21日 下午2:50:54
     */
    public class ExampleEvent extends BaseEvent {
    	private String userName;
    
    	public ExampleEvent(EventType evtType, String userName) {
    		super(evtType);
    		this.userName = userName;
    	}
    
    	public String getUserName() {
    		return userName;
    	}
    
    	public void setUserName(String userName) {
    		this.userName = userName;
    	}
    
    }
    

    (2)声明一个业务事件监听器

    package com.example.demo.eventdriven;
    
    /**
     * 
    * @ClassName: ExampleEventListener
    * @Description: 样例事件监听器(用于演示使用)
    * @Author: liulianglin
    * @DateTime 2022年4月21日 下午3:36:17
     */
    public class ExampleEventListener implements EventListener<ExampleEvent> {
    
    	@Override
    	public void handleEvent(ExampleEvent event) {
    		System.out.println("开始处理"+event.getEvtType()+"事件, 当前登陆用户名称="+event.getUserName());
    	}
    
    }
    

    这里注意,自定义的事件监听器需要声明到上面的EventListenerManager内部,如下图所示 :

    (3)编写测试类(基于Spring Boot环境)

    package com.example.demo.eventdriven;
    
    import org.junit.jupiter.api.Test;
    import org.springframework.boot.test.context.SpringBootTest;
    
    @SpringBootTest
    public class EventDrivenTest {
    	
    	@Test
    	void test() {
    		BaseEvent event = new ExampleEvent(EventType.LOGIN, "超级管理员");
    		event.setSync(false);
    		EventDispatcher.INSTANCE.dispatchEvent(event);
    		
    		try {
    			System.out.println("模拟业务处理1秒钟....");
    			Thread.sleep(1000);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		
    		System.out.println("处理完毕,关闭");
    		//EventDispatcher.INSTANCE.shutdown();
    	}
    }
    

    测试结果:

    完活儿。。。。 

    展开全文
  • 事件驱动风格+观察者模式java
  • Java 开发中事件驱动模型的实例详解,属于转的
  • Java实现事件驱动框架(一)

    千次阅读 2018-04-30 21:41:57
    上一篇文章中,我们介绍了事件驱动的基础组件。本文,我们将开发一个事件驱动的框架。 消息系统 事件驱动框架参照一些消息系统中的模式。我们将进行如下类比。 事件与消息,事件处理器与通道,事件转发器与路由...

    上一篇文章中,我们介绍了事件驱动的基础组件。本文,我们将开发一个事件驱动的框架。

    消息系统

    事件驱动框架参照一些消息系统中的模式。我们将进行如下类比。 事件与消息,事件处理器与通道,事件转发器与路由。

    一个实例是邮递系统。邮递员有一个背包里面有若干信件,上面有要寄送的地址,邮递员必须将信件寄送到相应的地址。这个过程可以按如下形式描述?

    procedure deliver_letters(satchel):
      repeat
        letter := next_letter(satchel)
        for home in homes do:
          if letter.destination == home:
            deliver_letter(home)
          end if
        end for
      until satchel is empty
    end procedure

    这个例子可以使用事件驱动编程建模。接下来我们将以最抽象的形式来开发一个框架,来对系统建模。

    消息

    每个消息有一个具体的类型,通过类型将消息与处理器相关联。消息接口定义如下。

    public interface Message {
      public Class<? extends Message> getType();
    }

    管道(Channel)

    管道与某种类型的消息关联。我们将消息派发给每种消息各自的管道进行处理。

    public interface Channel<E extends Message> {
      public void dispatch(E message);
    }

    动态路由

    消息系统的交互是通过路由完成。路由负责将给定的消息转发到具体的通道上。初始化阶段,路由会注册消息与其关联的通道。随后,由路由转发的消息会自动匹配消息类型及关联的管道,并将消息路由到关联的管道中。

    public interface DynamicRouter<E extends Message> {
      public void registerChannel(Class<? extends E> contentType,
          Channel<? extends E> channel);
      public abstract void dispatch(E content);
    }

    接下来将实现这些接口以便创建一个完整的框架。

    框架实现

    事件

    我们将事件定义为消息的子类。

    import Message;
    
    public class Event implements Message {
      @Override
      public Class<? extends Message> getType() {
        return getClass();
      }
    }

    处理器

    处理器最终接收事件,并处理,这里将实现管道接口。

    import Channel;
    
    public class Handler implements Channel<Event> {
      @Override
      public void dispatch(Event message) {
        System.out.println(message.getClass());
      }
    }

    事件转发器

    事件转发器用来注册消息与通道。本例中,我们注册处理器及其关联的事件类。我们使用HashMap将这件与处理器关联。

    import java.util.HashMap;
    import java.util.Map;
    
    import edu.giocc.util.router.Channel;
    import edu.giocc.util.router.DynamicRouter;
    
    public class EventDispatcher implements DynamicRouter<Event> {
      private Map<Class<? extends Event>, Handler> handlers;
    
      public EventDispatcher() {
        handlers = new HashMap<Class<? extends Event>, Handler>();
      }
    
      @Override
      public void registerChannel(Class<? extends Event> contentType,
          Channel<? extends Event> channel) {
        handlers.put(contentType, (Handler)channel);
      }
    
      @Override
      public void dispatch(Event content) {
        handlers.get(content.getClass()).dispatch(content);
      }
    }

    基本框架完成,接下来进行行测。

    public class Program {
      public static void main(String[] args) {
        EventDispatcher dispatcher = new EventDispatcher();
        dispatcher.registerChannel(Event.class, new Handler());
        dispatcher.dispatch(new Event());
      }
    }

    在应用程序中进行扩展

    现在框架已经建立,通用框架一般应具备下列特征。

    • 控制反转 如同消息系统一样,框架来控制数据流。
    • 扩展性 应用程序可根据使用来进行扩展。
    • 框架代码不可修改 不能修改框架代码。

    上述提到的属性解释了应用如何与框架连接。框架仅仅是架构的一个抽象。

    这里写图片描述

    Handler和Event类是framework层的类。基于框架开发的代码应该位于应用层。框架职责是抽象并提供事件驱动架构的基础工具。

    现在我们可以继承Handler类,来创建我们的事件处理器,继承Event类来创建我们的事件。此外,我们在派发器中注册这些事件处理器与事件。

    下一篇文章中将展示一个框架的具体实现,以便模拟事件驱动系统。

    原文地址

    http://www.giocc.com/writing-an-event-driven-framework-with-java.html

    展开全文
  • 事件驱动架构

    2012-12-10 12:02:32
    事件驱动架构Esper文档,Esper是一个开源的事件驱动框架,对于处理CEP,ESP的架构不错,比如事件监控、网络监控等等基于事件的模型。
  • java基于事件驱动之spring事件驱动

    千次阅读 2017-10-08 17:08:24
    事件驱动4个要素: 事件事件源、注册中心(事件通道)、侦听器。 事件驱动和观察者模式本质一样,事件驱动是观察者模式的经典实现。 事件驱动的好处: 1、 无耦合的关联,事件发布者和订阅者不需要预先知道彼此的存在...

    事件驱动4个要素:

    事件、事件源、注册中心(事件通道)、侦听器。

    事件驱动和观察者模式本质一样,事件驱动是观察者模式的经典实现。

    事件驱动的好处:

    1、 无耦合的关联,事件发布者和订阅者不需要预先知道彼此的存在。

    2、 异步消息传递,业务逻辑和事件可以同步发生。

    3、 多对多的交互,发布订阅模型。




    定义事件类:这个类需要继承ApplicationEvent类。

    注册事件的监听器:监听类需要实现ApplicationListener接口,并将泛型设置为具体的事件类。

    事件生产者:需要实现ApplicationContextAware接口,通过applicationContext.publishEvent()发布事件。

    注册中心:spring初始化的时候将所有的监听器放入集合中,当发布事件后spring会遍历集合将监听这个事件的所有监听器取出来依次执行监听代码。


    具体业务

    传统的业务流程,飞机票预定和发送短信、发送邮件耦合在一起,在同一个线程中,会出现如果短信或者邮件服务异常会引起主业务异常。所以需要通过事件驱动方式解耦。



    基于spring的事件驱动不止在代码级别解耦,一定要在线程级别解耦。配置事件异步支持(多线程方式),并通过线程池来实现不同的监听器用不同的线程。





    展开全文
  • Java classes when using the JDBC Thin and OCI client-side driver - with Java 7.0 VM. ojdbc6.jar Java classes when using the JDBC Thin and OCI client-side driver - with Java 6.0 VM. ojdbc5.jar Java ...
  • 这是一个Java事件总线框架,用于促进事件驱动的编程。 该框架的目的是提供一种生成和处理事件的简便方法。 鼓励仅将事件用作应用程序流程与第三方系统之间的通信方式。 这些文件可以通过其格式进行记录,操作,...
  • 事件驱动模型实例详解(Java篇)
  • java 连接mysql驱动

    2013-08-19 13:56:53
    java 连接mysql驱动
  • JAVA简单模拟一个事件驱动系统 模拟消息传递
  • Java基础———Java中的回调与事件

    千次阅读 2017-05-05 17:51:33
    1、基本概念  软件模块之间总是存在一定的联系,各个... 当服务方在检测到某种讯息或事件发生时主动通知客户方的机制,eg:驱动模块是服务方,界面模块是客户方。 2、C语言中的回调函数  回调函数是回调机制的一种
  • Java事件驱动模型实例详解

    千次阅读 2013-03-08 14:42:42
    或许每个软件从业者都有从学习控制台应用程序到学习可视化编程的转变过程,控制台应用程序的优点在于可以方便的练习某个语言的语法和开发习惯(如.net和java),而可视化编程的学习又可以非常方便开发出各类人机对话...
  • java事件驱动

    千次阅读 2013-02-18 21:01:11
    事件类的根类是java.util.EventObject 事件对象包括与事件相关的一切属性,可以使用EventObject中的实例方法getSource()获得事件的源对象。EventObject的子类的对象处理特定类型的事件。如动作事件,窗口事件,...
  • mysql数据库java驱动下载(jdbc)

    千次阅读 2022-04-18 14:32:29
    连接器/J 5.1提供了易于开发的特性,包括向驱动程序管理器自动注册、标准化的有效性检查、分类的SQLExceptions、对大量更新计数的支持、对来自java.time包、对JDBC-4.x XML处理的支持、对每个连接的客户端信息的支持...
  • java连接mysql数据库,数据库程序开发步骤首先就要加载JDBC驱动程序,不同版本的mysql数据库需要的MySQL数据库驱动程序jar包版本也不同。不少同学问怎么下载java连接mysql的驱动jar包?今天给大家分享:各版本MySQL...
  • Java运行程序找不到ODBC驱动

    万次阅读 2021-10-21 08:47:02
    Java运行程序找不到ODBC驱动解决方案:1.确保配置Access数据源正确2.查看Java版本 问题描述: 用java连接odbc的access数据库时出现错误, 配置数据源和账户名密码都是正常的。 错误提示: No suitable driver found...
  • Java连接SQL Server数据库驱动jdbc

    千次阅读 2021-01-19 22:23:43
    1、下载jdbc驱动 sqljdbc --Microsoft官网下载链接 备用:百度网盘链接: 提取码:2inu (8.4版本,支持jdk8、jdk11、jdk14) 2、打开下载好的驱动文件 ...选中Java项目中的jdbc驱动文件,右键选择 –Build Path
  • java事件驱动深度历险

    千次阅读 2005-04-18 22:58:00
    个人认为,java里面的事件的监听和处理是做得比较好的。而它结构的完美就不不是用语言来形容的了。在java里,接口的使用可以说是代表着一个人对java的理解和掌握程度。而那些所谓模式几乎全部是接口的使用,我在看...
  • linux64位下mysql64位,mysql驱动包mysql-connector-java-5.5.19.jar
  • mysql 驱动包 mysql-connect-java

    千次阅读 2021-11-20 01:53:22
    mysql的驱动包 mysql-connect-java 内部封装了jdbc: jdbc(java database connectivity):本身是由一组接口组成 , 可以使得Java编译来访问各种数据库 无需自己实现接口,这些接口的实现类由第三方数据库厂商实现 ...
  • mssqlserver2008java驱动

    热门讨论 2011-11-09 16:42:24
    java sqlserver2008 驱动,mssqlserver2008java驱动
  • 前言 生成一个圆,点击“放大”按钮,这个圆... 效果 代码 ControlCircle2.java: package Test; ...import javax.swing.*;...import java.awt.*;...import java.awt.event.ActionEvent;...import java.awt.event.ActionListene...
  • java连接打印机打印pdf文件,网上搜索了一大把资料,基本上都是重复。。。下面骂人的一大堆。。我这里来解决一下。需求:前端调用用接口 后端根据模版生成数据联通打印机直接一键打印!思路:这里讲一下打印最好使用...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 649,546
精华内容 259,818
关键字:

java事件驱动