科技有限公司可以做网站建设吗媒体代发网站

diannao/2025/10/17 14:49:36/文章来源:
科技有限公司可以做网站建设吗,媒体代发网站,金泉网是做网站的吗,网站内容侵权 怎么做文章目录 一、目标#xff1a;容器事件和事件监听器二、设计#xff1a;容器事件和事件监听器三、实现#xff1a;容器事件和事件监听器3.1 工程结构3.2 容器事件和事件监听器类图3.3 定义和实现事件3.3.1 定义事件抽象类3.3.2 定义应用上下文事件实现类3.3.3 上下文刷新事件… 文章目录 一、目标容器事件和事件监听器二、设计容器事件和事件监听器三、实现容器事件和事件监听器3.1 工程结构3.2 容器事件和事件监听器类图3.3 定义和实现事件3.3.1 定义事件抽象类3.3.2 定义应用上下文事件实现类3.3.3 上下文刷新事件类3.3.4 上下文关闭事件类 3.4 事件监听器3.4.1 类工具类添加判断代理对象3.4.2 事件监听器 3.5 事件广播器3.5.1 事件广播器接口3.5.2 事件广播器抽象类3.5.3 简单事件广播器 3.6 事件发布者的定义和实现3.6.1 定义事件发布者3.6.2 应用上下文接口3.6.3 应用上下文抽象类 四、测试容器事件和事件监听器4.1 添加测试配置4.1.1 创建自定义事件4.1.2 自定义事件监听器4.1.3 自定义事件刷新监听器4.1.4 自定义事件关闭监听器4.1.5 配置文件 4.2 单元测试 五、总结容器事件和事件监听器 一、目标容器事件和事件监听器 如何处理解耦什么是事件如何使用事件功能 在 Spring 中有一个 Event 事件功能它可以提供事件的定义、发布以及监听事件来完成一些自定义的动作。 比如你可以定义一个新用户注册的事件当有用户执行注册完成后在事件监听中给用户发送一些优惠券和短信提醒。这样的操作就可以把属于基本功能的注册和对应的策略服务分开降低系统的耦合。以后再扩展注册服务比如需要添加风控策略、添加实名认证、判断用户属性等都不会影响到依赖注册成功后执行的动作。 本节需要以观察者模式的方式设计和实现 Spring Event 的容器事件和事件监听器功能。 最终可以让 Spring 框架可以定义、监听和发布自己的事件信息。 二、设计容器事件和事件监听器 设计观察者模式实现 Spring Event 容器时间和事件监听器。 事件 的设计本身就是一种观察者模式的实现它所要解决的就是一个对象状态改变给其他对象通知的问题而且要考虑到易用和低耦合保证高度的协作。再功能上我们需要定义事件类、事件监听、事件发布。 这些类的功能需要结合到 Spring 的 AbstractApplicationContext#refresh()以便于处理事件初始化和注册事件监听器的操作。 在整个功能实现过程中需要在面向用户的应用上下文 AbstractApplicationContext 中添加相关事件内容。 包括初始化事件发布者、注册事件监听器、发布容器刷新完成事件。 使用观察者模式定义事件类、监听类、发布类同时还需要完成一个广播器的功能。 接收到事件推送时进行分析处理符合监听事件接收者感兴趣的事件也就是使用 isAssignableFrom 进行判断。 isAssignableFrom 和 instanceof 相似不过 isAssignableFrom 是用来判断子类和父类的关系的或者接口的实现类和接口的关系。 默认所有的类的终极父类都是 Object。如果 A.isAssignableFrom(B) 结果是 true证明 B 可以转换成 A也就是 A 可以由 B 转换而来。 三、实现容器事件和事件监听器 3.1 工程结构 spring-step-10 |-src|-main| |-java| |-com.lino.springframework| |-beans| | |-factory| | | |-config| | | | |-AutowireCapableBeanFactory.java| | | | |-BeanDefinition.java| | | | |-BeanFactoryPostProcessor.java| | | | |-BeanPostProcessor.java| | | | |-BeanReference.java| | | | |-ConfigurableBeanFactory.java| | | | |-SingletonBeanRegistry.java| | | |-support| | | | |-AbstractAutowireCapableBeanFactory.java| | | | |-AbstractBeabDefinitionReader.java| | | | |-AbstractBeabFactory.java| | | | |-BeabDefinitionReader.java| | | | |-BeanDefinitionRegistry.java| | | | |-CglibSubclassingInstantiationStrategy.java| | | | |-DefaultListableBeanFactory.java| | | | |-DefaultSingletonBeanRegistry.java| | | | |-DisposableBeanAdapter.java| | | | |-FactoryBeanRegistrySupport.java| | | | |-InstantiationStrategy.java| | | | |-SimpleInstantiationStrategy.java| | | |-support| | | | |-XMLBeanDefinitionReader.java| | | |-Aware.java| | | |-BeanClassLoaderAware.java| | | |-BeanFactory.java| | | |-BeanFactoryAware.java| | | |-BeanNameAware.java| | | |-ConfigurableListableBeanFactory.java| | | |-DisposableBean.java| | | |-FactoryBean.java| | | |-HierarcgicalBeanFactory.java| | | |-InitializingBean.java| | | |-ListableBeanFactory.java| | |-BeansException.java| | |-PropertyValue.java| | |-PropertyValues.java| |-context| | |-event| | | |-AbstractApplicationEventMulticaster.java| | | |-ApplicationContextEvent.java| | | |-ApplicationEventMulticaster.java| | | |-ContextclosedEvent.java| | | |-ContextRefreshedEvent.java| | | |-SimpleApplicationEventMulticaster.java| | |-support| | | |-AbstractApplicationContext.java| | | |-AbstractRefreshableApplicationContext.java| | | |-AbstractXmlApplicationContext.java| | | |-ApplicationContextAwareProcessor.java| | | |-ClassPathXmlApplicationContext.java| | |-ApplicationContext.java| | |-ApplicationContextAware.java| | |-ApplicationEvent.java| | |-ApplicationEventPublisher.java| | |-ApplicationListener.java| | |-ConfigurableApplicationContext.java| |-core.io| | |-ClassPathResource.java| | |-DefaultResourceLoader.java| | |-FileSystemResource.java| | |-Resource.java| | |-ResourceLoader.java| | |-UrlResource.java| |-util| | |-ClassUtils.java|-test|-java|-com.lino.springframework.test|-event| |-CustomClosedEventListener.java| |-CustomEvent.java| |-CustomEventListener.java| |-CustomRefreshedEventListener.java|-ApiTest.java|-resources|-spring.xml3.2 容器事件和事件监听器类图 整个类图以围绕实现 event 事件定义、发布、监听功能实现和把事件相关内容使用 AbstractApplicationContext#refresh 进行注册和处理操作。在实现的过程中主要以扩展 spring context 包为主事件的实现也是在这个包下进行扩展的当然也可以看出来目前所有的实现内容仍然是以 IOC 为主。ApplicationContext 容器继承事件发布功能接口 ApplicationEventPublisher并在实现类中提供事件监听功能。ApplicationEventMulticaster 接口是注册监听器和发布事件的广播器提供添加、移除和发布事件方法。最后是发布容器关闭事件这个仍然需要扩展到 AbstractApplicationContext#close 方法中由注册到虚拟机的钩子实现。 3.3 定义和实现事件 3.3.1 定义事件抽象类 ApplicationEvent.java package com.lino.springframework.context;import java.util.EventObject;/*** description: 定义事件抽象类*/ public abstract class ApplicationEvent extends EventObject {/*** Constructs a prototypical Event.** param source The object on which the Event initially occurred.* throws IllegalArgumentException if source is null.*/public ApplicationEvent(Object source) {super(source);} }以继承 java.util.EventObject 定义出具备事件功能的抽象类 ApplicationEvent后续所有事件的类都需要继承这个类。 3.3.2 定义应用上下文事件实现类 ApplicationContextEvent.java package com.lino.springframework.context.event;import com.lino.springframework.context.ApplicationContext; import com.lino.springframework.context.ApplicationEvent;/*** description: 定义应用上下文事件实现类*/ public class ApplicationContextEvent extends ApplicationEvent {/*** Constructs a prototypical Event.** param source The object on which the Event initially occurred.* throws IllegalArgumentException if source is null.*/public ApplicationContextEvent(Object source) {super(source);}/*** 获取应用上下文** return 应用上下文*/public final ApplicationContext getApplicationContext() {return (ApplicationContext) getSource();} }3.3.3 上下文刷新事件类 ContextRefreshedEvent.java package com.lino.springframework.context.event;/*** description: 上下文刷新事件类*/ public class ContextRefreshedEvent extends ApplicationContextEvent {/*** Constructs a prototypical Event.** param source The object on which the Event initially occurred.* throws IllegalArgumentException if source is null.*/public ContextRefreshedEvent(Object source) {super(source);} }3.3.4 上下文关闭事件类 ContextClosedEvent.java package com.lino.springframework.context.event;/*** description: 上下文关闭事件类*/ public class ContextClosedEvent extends ApplicationContextEvent {/*** Constructs a prototypical Event.** param source The object on which the Event initially occurred.* throws IllegalArgumentException if source is null.*/public ContextClosedEvent(Object source) {super(source);} }ApplicationContextEvent 是定义事件的类所有的事件包括关闭、刷新以及用户自己实现的事件都需要继承这个类。ContextRefreshedEvent、ContextClosedEvent分别是 Spring 框架自己实现的两个事件类可以用于监听刷新和关闭动作。 3.4 事件监听器 3.4.1 类工具类添加判断代理对象 ClassUtils.java package com.lino.springframework.util;/*** description: 类工具类*/ public class ClassUtils {/*** 获取默认类加载器** return 类加载器*/public static ClassLoader getDefaultClassLoader() {ClassLoader cl null;try {cl Thread.currentThread().getContextClassLoader();} catch (Throwable ex) {// Cannot access thread context ClassLoader - falling back to system class loader...}if (cl null) {// No thread context class loader - use class loader of this class.cl ClassUtils.class.getClassLoader();}return cl;}/*** 判断类是否是cglib代理对象** param clazz 类* return 是否是cglib代理对象*/public static boolean isCglibProxyClass(Class? clazz) {return (clazz ! null isCglibProxyClassName(clazz.getName()));}/*** 判断类名是否符合cglib代理类命名** param className 类名* return 是否符合cglib代理类命名*/public static boolean isCglibProxyClassName(String className) {return (className ! null className.contains($$));} }添加判断是否是 cglib 代理对象和是否符合 cglib 代理名称的方法。 3.4.2 事件监听器 ApplicationListener.java package com.lino.springframework.context;import java.util.EventListener;/*** description: 事件监听器* author: lingjian* createDate: 2022/12/1 15:01*/ public interface ApplicationListenerE extends ApplicationEvent extends EventListener {/*** 处理事件** param event 事件*/void onApplicationEvent(E event); }添加监听器开放接口后续开放给外部实现调用。 3.5 事件广播器 3.5.1 事件广播器接口 ApplicationEventMulticaster.java package com.lino.springframework.context.event;import com.lino.springframework.context.ApplicationEvent; import com.lino.springframework.context.ApplicationListener;/*** description: 事件广播器*/ public interface ApplicationEventMulticaster {/*** 添加监听器** param listener 监听器*/void addApplicationListener(ApplicationListener? listener);/*** 删除监听器** param listener 监听器*/void removeApplicationListener(ApplicationListener? listener);/*** 广播事件** param event 事件*/void multicastEvent(ApplicationEvent event); }在事件广播器中定义了添加监听和删除监听的方法以及一个广播事件的方法 multicastEvent。最终推送时间消息也会经过这个接口方法来处理谁该接收事件。 3.5.2 事件广播器抽象类 AbstractApplicationEventMulticaster.java package com.lino.springframework.context.event;import com.lino.springframework.beans.BeansException; import com.lino.springframework.beans.factory.BeanFactory; import com.lino.springframework.beans.factory.BeanFactoryAware; import com.lino.springframework.context.ApplicationEvent; import com.lino.springframework.context.ApplicationListener; import com.lino.springframework.util.ClassUtils; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Collection; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.Set;/*** description: 事件广播器抽象类*/ public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster, BeanFactoryAware {public final SetApplicationListenerApplicationEvent applicationListeners new LinkedHashSet();private BeanFactory beanFactory;Overridepublic void addApplicationListener(ApplicationListener? listener) {applicationListeners.add((ApplicationListenerApplicationEvent) listener);}Overridepublic void removeApplicationListener(ApplicationListener? listener) {applicationListeners.remove(listener);}Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory beanFactory;}/*** 获取事件监听器** param event 事件* return 监听器列表*/protected CollectionApplicationListener getApplicationListeners(ApplicationEvent event) {LinkedListApplicationListener allListeners new LinkedList();for (ApplicationListenerApplicationEvent listener : applicationListeners) {if (supportsEvent(listener, event)) {allListeners.add(listener);}}return allListeners;}/*** 监听器是否该事件感兴趣** param applicationListener 监听器* param event 事件* return 是否感兴趣*/protected boolean supportsEvent(ApplicationListenerApplicationEvent applicationListener, ApplicationEvent event) {Class? extends ApplicationListener listenerClass applicationListener.getClass();// 按照 CglibSubclassingInstantiationStrategy、SimpleInstantiationStrategy 不同的实例化类型需要判断后获取目标 classClass? targetClass ClassUtils.isCglibProxyClass(listenerClass) ? listenerClass.getSuperclass() : listenerClass;Type genericInterface targetClass.getGenericInterfaces()[0];Type actualTypeArgument ((ParameterizedType) genericInterface).getActualTypeArguments()[0];String className actualTypeArgument.getTypeName();Class? eventClassName;try {eventClassName Class.forName(className);} catch (ClassNotFoundException e) {throw new BeansException(wrong event class name: className);}// 判断此 eventClassName 对象所表示的类或接口与指定的 event.getClass() 参数所表示的类或接口是否相同或是否是超类或超接口// isAssignableFrom是用来判断子类和父类的关系的或者接口的实现类和接口的关系的默认所有的类的终极父类都是Object。// 如果A.isAssignableFrom(B)结果是true证明B可以转换成为A也就是A可以由B转换而来。return eventClassName.isAssignableFrom(event.getClass());} }AbstractApplicationEventMulticaster 是对事件广播器的公用方法提取在这个类中可以实现一些基本功能避免所有直接实现接口还需要处理细节。除了像 addApplicationListener、removeApplicationListener 这样的通用方法。这里主要是对 getApplicationListeners、supportsEvent 的处理。 getApplicationListeners主要是摘取符合广播事件中的监听处理器具体过滤动作在 supportsEvent 方法中。supportsEvent 主要包括对 Cglib、Simple 不同实例化需要获取父类的 ClassCglib 代理类需要获取父类的 Class。普通实例化则不需要。接下来就是通过提取接口和对应的 ParameterizedType 和 eventClassName方便最后确认是否为子类和父类的关系以此证明此事件归这个符合的类处理。 从结果看出最终 eventClassName 和 event.getClass() 在 isAssignableFrom 判断下为 true。关于 CglibSubclassingInstantiationStrategy、SimpleInstantiationStrategy 可以尝试在 AbstractApplicationContext 类中更换验证。 3.5.3 简单事件广播器 SimpleApplicationEventMulticaster.java package com.lino.springframework.context.event;import com.lino.springframework.beans.factory.BeanFactory; import com.lino.springframework.context.ApplicationEvent; import com.lino.springframework.context.ApplicationListener;/*** description: 简单事件广播器*/ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {public SimpleApplicationEventMulticaster(BeanFactory beanFactory) {setBeanFactory(beanFactory);}SuppressWarnings(unchecked)Overridepublic void multicastEvent(final ApplicationEvent event) {for (final ApplicationListener listener : getApplicationListeners(event)) {listener.onApplicationEvent(event);}} }3.6 事件发布者的定义和实现 3.6.1 定义事件发布者 ApplicationEventPublisher.java package com.lino.springframework.context;/*** description: 事件发布者接口*/ public interface ApplicationEventPublisher {/*** 发布事件** param event 事件*/void publishEvent(ApplicationEvent event); }ApplicationEventPublisher 是一个事件的发布接口所有的事件都需要从这个接口发布出去。 3.6.2 应用上下文接口 ApplicationContext.java package com.lino.springframework.context;import com.lino.springframework.beans.factory.HierarchicalBeanFactory; import com.lino.springframework.beans.factory.ListableBeanFactory; import com.lino.springframework.core.io.ResourceLoader;/*** description: 应用上下文接口*/ public interface ApplicationContext extends ListableBeanFactory, HierarchicalBeanFactory, ResourceLoader, ApplicationEventPublisher { }3.6.3 应用上下文抽象类 AbstractApplicationContext.java package com.lino.springframework.context.support;import com.lino.springframework.beans.BeansException; import com.lino.springframework.beans.factory.ConfigurableListableBeanFactory; import com.lino.springframework.beans.factory.config.BeanFactoryPostProcessor; import com.lino.springframework.beans.factory.config.BeanPostProcessor; import com.lino.springframework.context.ApplicationEvent; import com.lino.springframework.context.ApplicationListener; import com.lino.springframework.context.ConfigurableApplicationContext; import com.lino.springframework.context.event.ApplicationEventMulticaster; import com.lino.springframework.context.event.ContextClosedEvent; import com.lino.springframework.context.event.ContextRefreshedEvent; import com.lino.springframework.context.event.SimpleApplicationEventMulticaster; import com.lino.springframework.core.io.DefaultResourceLoader; import java.util.Collection; import java.util.Map;/*** description: 抽象应用上下文*/ public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME applicationEventMulticaster;private ApplicationEventMulticaster applicationEventMulticaster;Overridepublic void refresh() throws BeansException {// 1.创建 BeanFactory并加载 BeanDefinitionrefreshBeanFactory();// 2.获取 BeanFactoryConfigurableListableBeanFactory beanFactory getBeanFactory();// 3.添加 ApplicationContextAwareProcessor让继承自 ApplicationContextAware 的 Bean 对象都能感知所属的 ApplicationContextbeanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));// 4.在 Bean 实例化之前执行 BeanFactoryPostProcessinvokeBeanFactoryPostProcessor(beanFactory);// 5.BeanPostProcessor 需要提前与其他 Bean 对象实例化之前执行注册操作registerBeanPostProcessor(beanFactory);// 6.初始化事件发布者initApplicationEventMulticaster();// 7.注册事件监听器registerListeners();// 8.提前实例化单例 Bean 对象beanFactory.preInstantiateSingletons();// 9.发布容器刷新完成事件finishRefresh();}...private void initApplicationEventMulticaster() {ConfigurableListableBeanFactory beanFactory getBeanFactory();applicationEventMulticaster new SimpleApplicationEventMulticaster(beanFactory);beanFactory.registerSingletonBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, applicationEventMulticaster);}private void registerListeners() {CollectionApplicationListener applicationListeners getBeansOfType(ApplicationListener.class).values();for (ApplicationListener listener : applicationListeners) {applicationEventMulticaster.addApplicationListener(listener);}}private void finishRefresh() {publishEvent(new ContextRefreshedEvent(this));}Overridepublic void publishEvent(ApplicationEvent event) {applicationEventMulticaster.multicastEvent(event);}...Overridepublic void close() {// 发布容器关闭事件publishEvent(new ContextClosedEvent(this));// 执行销毁单例bean的销毁方法getBeanFactory().destroySingletons();}}在抽象应用上下文 AbstractApplicationContext#refresh 中主要新增了 初始化事件发布者、注册事件监听器、发布容器刷新完成事件。三个方法用于处理事件操作。 初始化事件发布者(initApplicationEventMulticaster)主要用于实例化一个 SimpleApplicationEventMulticaster这是一个事件广播器。注册事件监听器(registerListeners)通过 getBeansOfType 方法获取到所有从 spring.xml 中加载到的事件配置 Bean 对象。发布容器刷新完成事件(finishRefresh)发布了第一个服务器启动完成后的事件这个事件通过 publishEvent 发布出去其实也就是调用了 applicationEventMulticaster.multicastEvent(event) 方法。关闭方法(close)新增加了发布一个容器关闭事件。publishEvent(new ContextClosedEvent(this))。 四、测试容器事件和事件监听器 4.1 添加测试配置 4.1.1 创建自定义事件 CustomEvent.java package com.lino.springframework.test.event;import com.lino.springframework.context.event.ApplicationContextEvent;/*** description: 自定义事件*/ public class CustomEvent extends ApplicationContextEvent {private Long id;private String message;/*** Constructs a prototypical Event.** param source The object on which the Event initially occurred.* throws IllegalArgumentException if source is null.*/public CustomEvent(Object source, Long id, String message) {super(source);this.id id;this.message message;}public Long getId() {return id;}public void setId(Long id) {this.id id;}public String getMessage() {return message;}public void setMessage(String message) {this.message message;} }创建一个自定义事件在事件类的构造函数中可以添加自己想要的入参信息。这个事件类最终会被完成的监听类监听到所以你添加的属性也会被获得到。 4.1.2 自定义事件监听器 CustomEventListener.java package com.lino.springframework.test.event;import com.lino.springframework.context.ApplicationListener; import java.util.Date;/*** description: 自定义事件监听器*/ public class CustomEventListener implements ApplicationListenerCustomEvent {Overridepublic void onApplicationEvent(CustomEvent event) {System.out.println(收到 event.getSource() 消息;时间 new Date());System.out.println(消息 event.getId() : event.getMessage());} }这是一个用于监听 CustomEvent 事件的监听器这里可以处理自定义操作。 4.1.3 自定义事件刷新监听器 CustomRefreshedEventListener.java package com.lino.springframework.test.event;import com.lino.springframework.context.ApplicationListener; import com.lino.springframework.context.event.ContextRefreshedEvent;/*** description: 自定义事件刷新监听器* author: lingjian* createDate: 2022/12/1 15:48*/ public class CustomRefreshedEventListener implements ApplicationListenerContextRefreshedEvent {Overridepublic void onApplicationEvent(ContextRefreshedEvent event) {System.out.println(刷新事件 this.getClass().getName());} }4.1.4 自定义事件关闭监听器 CustomClosedEventListener.java package com.lino.springframework.test.event;import com.lino.springframework.context.ApplicationListener; import com.lino.springframework.context.event.ContextClosedEvent;/*** description: 自定义事件关闭监听器*/ public class CustomClosedEventListener implements ApplicationListenerContextClosedEvent {Overridepublic void onApplicationEvent(ContextClosedEvent event) {System.out.println(关闭事件 this.getClass().getName());} }4.1.5 配置文件 spring.xml ?xml version1.0 encodingutf-8 ? beansbean classcom.lino.springframework.test.event.CustomEventListener/bean classcom.lino.springframework.test.event.CustomRefreshedEventListener/bean classcom.lino.springframework.test.event.CustomClosedEventListener/ /beans在 spring.xml 配置文件中添加了三个事件监听器监听刷新、监控自定义事件、监听关闭事件。 4.2 单元测试 ApiTest.java Test public void test_event() {// 1.初始化 BeanFactoryClassPathXmlApplicationContext applicationContext new ClassPathXmlApplicationContext(classpath:spring.xml);applicationContext.publishEvent(new CustomEvent(applicationContext, 1019129009086763L, 成功监听到了));applicationContext.registerShutdownHook(); }通过使用 applicationContext 新增加的发布事件接口方法发布一个自定义事件 CustomEvent并传了相应的参数信息。 测试结果 刷新事件com.lino.springframework.test.event.CustomRefreshedEventListener$$EnhancerByCGLIB$$b3c3d48f 收到com.lino.springframework.context.support.ClassPathXmlApplicationContext4cdbe50f消息;时间Thu Dec 01 17:07:43 CST 2022 消息1019129009086763:成功监听到了 关闭事件com.lino.springframework.test.event.CustomClosedEventListener$$EnhancerByCGLIB$$20578a33从测试结果看我们自定义的事件和监听以及监听系统的事件信息都可以在控制台完成的输出。 五、总结容器事件和事件监听器 在现有的 Spring 的实现过程中可以逐步看到很多设计模式的使用。 比如简单工厂 BeanFactory、工厂方法 FactoryBean、策略模式访问资源、观察者模式 Event。 本节关于观察者模式的实现过程主要包括了事件的定义、事件的监听和发布事件发布完成后根据匹配策略监听器就会收到属于自己的事件内容并做相应的处理动作。在结合 Spring 后可以看到如何把观察者的实现和应用上下文结合。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/92212.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何让网站上线中国最大的外贸平台

随着软件行业的飞速发展,互联网公司对开发者的技能要求也越来越高。而高并发、网络编程、微服务、海量数据的处理等技能,是每一个开发者进阶时的必学知识。为了帮助初级开发者快速掌握这些实用技术,本书以“理论+范例”的形式对各…

国内站长做国外网站php网站后台入口

获取源码资料,请移步从戎源码网:从戎源码网_专业的计算机毕业设计网站 项目介绍 基于springboot的学习英语管理系统:前端 thymeleaf、jquery,后端 maven、springmvc、spring、mybatis,角色分为管理员、用户&#xff…

设计单网站建设自己做视频网站如何接广告

基于Matlab的数据可视化 一、二维图形的绘制(一)基本图形函数(1)plot函数(2)fplot函数(3)其他坐标系的二维曲线 (二)图形属性设置(1)线…

网站集约化 建设方案电子商务网络营销的特点

使用 Spring Authorization Server 实现具有 PKCE 的单页应用程序进行身份验证 开启 CORS SPA 由静态资源组成,可以通过多种方式进行部署。它可以与后端分开部署,例如使用 CDN 或单独的 Web 服务器,也可以使用 Spring Boot 与后端一起部署。…

公司网站服务器租赁免费做ppt的网站

异地组网安装是指在不同地域的多个设备之间建立网络连接,以便实现数据传输和协同工作的过程。在如今的数字化时代,异地组网安装已经成为了许多企业和组织所必需的一项技术。 天联的使用场景 在异地组网安装中,天联是一种常用的工具。它具有以…

网站做seo收录wordpress 设置ftp

1、事务简介 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。在关系数据库中,一个事务由一组SQL语句组成,事务具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID原则。 原子性(atomici…

网站为什么被挂马长久新开传奇网站

distinct MongoDB 的 distinct 命令是获取特定字段中不同值列表的最简单工具。 该命令适用于普通字段、数组字段以及数组内嵌文档(集合对象)。 db.getCollection(customer).distinct("customer_type")// chances字段的值是个集合,获…

html5行业网站企业服务中心抖音

当构建高可用的网络应用时,负载均衡是至关重要的技术之一。Nginx 是一个强大的开源反向代理服务器,提供了丰富的负载均衡功能,包括负载均衡算法和健康检查。在本篇博客中,我们将讨论如何使用 Nginx 进行负载均衡,并结合…

门户网站推广优势小程序开发定制公司北京

一:题目 二:思路 1.这个题不能用优先队列,虽然我们可以通过优先队列得到最大值,但是我们在移动 窗口的时候,便不可以正常的删除元素了 2.虽然不能用优先对列,但是我们依然希望可以得到队首的元素的时候是最大值,同时还…

网站的下拉列表怎么做洛阳php网站开发

题目背景:目前往往需要对测序后的序列进行聚类与比对。其中聚类指的是将测序序列聚类以判断原始序列有多少条,聚类后相同类的序列定义为一个簇。比对则是指在聚类基础上对一个簇内的序列进行比对进而输出一条最有 可能的正确序列。通过聚类与比对将会极大…

建设网站主机可以用吗做软件开发有前途吗

Makefile中: ? 的区别 在Makefile中我们经常看到 : ? 这几个赋值运算符,那么他们有什么区别呢?我们来做个简单的实验 新建一个Makefile,内容为: ifdef DEFINE_VRE VRE “Hello World!” else endif ifeq ($(OPT),define) VRE…

工伤做实的那个网站找人做网站大概多少钱

有这样一个3位数,组成它的3个数字阶乘之和正好等于它本身。 即:abc a! b! c! 请找出所有满足要求的三位数.审好题很重要:三位数而非,三位数的个数 先写出一个函数求出某个数的阶乘,在跟别求出一个三位数的个十百位&…

178网站建设西安买公司的网站建设

今天在使用souce建表的时候发现自己表结构中的中文出现了乱码问题,那么具体的解决方案如下: 首先我们先使用命令行连接自己的数据库 mysql -u root -p 12345 然后使用show variables like "char%"; 如果说你的这个里面不是utf-8那么就是出现了…

php网站建设价格临沂制作网站软件

恕我直言,我一直都用 git pull 从来没有用过 git fetch git fetch, git pull 都可以用于获取远程仓库的内容,但它们有不同的作用和用法。 git fetch 用途:git fetch 用于从远程仓库获取最新的提交,但不会自动合并或更新本地分支…

网站访客qq获取系统 报价织梦小说网站源wap站

贴片陶瓷气体放电管 GDT工作原理GDT主要特性参数典型电路压敏电阻与 TVS 管的区别 GDT工作原理 陶瓷气体放电管是一种电子器件,其工作原理基于气体放电现象。这种管子的内部填充了一种特定的气体,通常是氖气或氩气。当管子两端施加足够的电压时&#xf…

福清营销型网站建设方案qq的seo综合查询

购买装备 发布时间: 2017年7月9日 18:17 最后更新: 2017年7月9日 21:05 时间限制: 1000ms 内存限制: 128M 描述 最近盛大的一款游戏传奇世界极其火爆。游戏玩家John,想购买游戏中的装备。已知游戏的商店里有n件装备,第i件装备具有属性值ai&#xf…

更新网站的图片加不上水印云服务器做网站一般配置

自动控制:控制系统的稳定性 在自动控制领域,控制系统的稳定性是一个至关重要的问题。稳定性决定了系统在受到扰动后是否能够恢复到平衡状态。本文将介绍控制系统稳定性的基本概念、如何利用特征值分析稳定性,并通过具体示例和Python代码展示…

网站设计和平面设计拆分盘网站建设

⭐简单说两句⭐ ✨ 正在努力的小新~ 💖 超级爱分享,分享各种有趣干货! 👩‍💻 提供:模拟面试 | 简历诊断 | 独家简历模板 🌈 感谢关注,关注了你就是我的超级粉丝啦! &…

psd 网站唯美wordpress简约主题

前言:堆算是一种相对简单的数据结构, 本篇文章将详细的讲解堆中的知识点, 包括那些我们第一次学习堆的时候容易忽略的内容, 本篇文章会作为重点详细提到。 本篇内容适合已经学完C语言数组和函数部分的友友们观看。 目录 什么是堆 建堆算法…

美工设计网站推荐seo多久可以学会

基于3Blue1Brown视频的笔记 一种新的看待方式 对于一个向量,比如说,如何看待其中的3和-2? 一开始,我们往往将其看作长度(从向量的首走到尾部,分别在x和y上走的长度)。 在有了数乘后&#xff0…