Closed unknowIfGuestInDream closed 1 year ago
参考SpringBoot event的实现
考虑调用者 通过线程池来执行
考虑给InterfaceScanner 中加缓存来优化启动时初始化性能
参考: https://www.hangge.com/blog/cache/detail_3259.html https://github.com/unknowIfGuestInDream/DesignpatternTest/blob/master/src/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F/%E5%9F%BA%E4%BA%8EJavaAPI%E5%AE%9E%E7%8E%B0%E9%80%9A%E7%9F%A5%E6%9C%BA%E5%88%B6/Test.java
JDK 不仅提供了 Observable 类、Observer 接口用来支持观察者模式,而且也提供了 EventObject、EventListener 接口来支持事件监听模式。虽然两者属于同一类型模式,都属于回调机制、主动推送消息,但使用场景有些区别,或者说监听器模式是观察者模式在特定场景下的一种改造和应用......
GitHub设计模式练习. Contribute to unknowIfGuestInDream/DesignpatternTest development by creating an account on GitHub.
/**
* Class to be extended by all application events. Abstract as it
* doesn't make sense for generic events to be published directly.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @see org.springframework.context.ApplicationListener
* @see org.springframework.context.event.EventListener
*/
public abstract class ApplicationEvent extends EventObject {
/** use serialVersionUID from Spring 1.2 for interoperability. */
private static final long serialVersionUID = 7099057708183571937L;
/** System time when the event happened. */
private final long timestamp;
/**
* Create a new {@code ApplicationEvent} with its {@link #getTimestamp() timestamp}
* set to {@link System#currentTimeMillis()}.
* @param source the object on which the event initially occurred or with
* which the event is associated (never {@code null})
* @see #ApplicationEvent(Object, Clock)
*/
public ApplicationEvent(Object source) {
super(source);
this.timestamp = System.currentTimeMillis();
}
/**
* Create a new {@code ApplicationEvent} with its {@link #getTimestamp() timestamp}
* set to the value returned by {@link Clock#millis()} in the provided {@link Clock}.
* <p>This constructor is typically used in testing scenarios.
* @param source the object on which the event initially occurred or with
* which the event is associated (never {@code null})
* @param clock a clock which will provide the timestamp
* @since 5.3.8
* @see #ApplicationEvent(Object)
*/
public ApplicationEvent(Object source, Clock clock) {
super(source);
this.timestamp = clock.millis();
}
/**
* Return the time in milliseconds when the event occurred.
* @see #ApplicationEvent(Object)
* @see #ApplicationEvent(Object, Clock)
*/
public final long getTimestamp() {
return this.timestamp;
}
}
/**
* Annotation that marks a method as a listener for application events.
*
* <p>If an annotated method supports a single event type, the method may
* declare a single parameter that reflects the event type to listen to.
* If an annotated method supports multiple event types, this annotation
* may refer to one or more supported event types using the {@code classes}
* attribute. See the {@link #classes} javadoc for further details.
*
* <p>Events can be {@link ApplicationEvent} instances as well as arbitrary
* objects.
*
* <p>Processing of {@code @EventListener} annotations is performed via
* the internal {@link EventListenerMethodProcessor} bean which gets
* registered automatically when using Java config or manually via the
* {@code <context:annotation-config/>} or {@code <context:component-scan/>}
* element when using XML config.
*
* <p>Annotated methods may have a non-{@code void} return type. When they
* do, the result of the method invocation is sent as a new event. If the
* return type is either an array or a collection, each element is sent
* as a new individual event.
*
* <p>This annotation may be used as a <em>meta-annotation</em> to create custom
* <em>composed annotations</em>.
*
* <h3>Exception Handling</h3>
* <p>While it is possible for an event listener to declare that it
* throws arbitrary exception types, any checked exceptions thrown
* from an event listener will be wrapped in an
* {@link java.lang.reflect.UndeclaredThrowableException UndeclaredThrowableException}
* since the event publisher can only handle runtime exceptions.
*
* <h3>Asynchronous Listeners</h3>
* <p>If you want a particular listener to process events asynchronously, you
* can use Spring's {@link org.springframework.scheduling.annotation.Async @Async}
* support, but be aware of the following limitations when using asynchronous events.
*
* <ul>
* <li>If an asynchronous event listener throws an exception, it is not propagated
* to the caller. See {@link org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler
* AsyncUncaughtExceptionHandler} for more details.</li>
* <li>Asynchronous event listener methods cannot publish a subsequent event by returning a
* value. If you need to publish another event as the result of the processing, inject an
* {@link org.springframework.context.ApplicationEventPublisher ApplicationEventPublisher}
* to publish the event manually.</li>
* </ul>
*
* <h3>Ordering Listeners</h3>
* <p>It is also possible to define the order in which listeners for a
* certain event are to be invoked. To do so, add Spring's common
* {@link org.springframework.core.annotation.Order @Order} annotation
* alongside this event listener annotation.
*
* @author Stephane Nicoll
* @author Sam Brannen
* @since 4.2
* @see EventListenerMethodProcessor
* @see org.springframework.transaction.event.TransactionalEventListener
*/
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EventListener {
/**
* Alias for {@link #classes}.
*/
@AliasFor("classes")
Class<?>[] value() default {};
/**
* The event classes that this listener handles.
* <p>If this attribute is specified with a single value, the
* annotated method may optionally accept a single parameter.
* However, if this attribute is specified with multiple values,
* the annotated method must <em>not</em> declare any parameters.
*/
@AliasFor("value")
Class<?>[] classes() default {};
/**
* Spring Expression Language (SpEL) expression used for making the event
* handling conditional.
* <p>The event will be handled if the expression evaluates to boolean
* {@code true} or one of the following strings: {@code "true"}, {@code "on"},
* {@code "yes"}, or {@code "1"}.
* <p>The default expression is {@code ""}, meaning the event is always handled.
* <p>The SpEL expression will be evaluated against a dedicated context that
* provides the following metadata:
* <ul>
* <li>{@code #root.event} or {@code event} for references to the
* {@link ApplicationEvent}</li>
* <li>{@code #root.args} or {@code args} for references to the method
* arguments array</li>
* <li>Method arguments can be accessed by index. For example, the first
* argument can be accessed via {@code #root.args[0]}, {@code args[0]},
* {@code #a0}, or {@code #p0}.</li>
* <li>Method arguments can be accessed by name (with a preceding hash tag)
* if parameter names are available in the compiled byte code.</li>
* </ul>
*/
String condition() default "";
/**
* An optional identifier for the listener, defaulting to the fully-qualified
* signature of the declaring method (e.g. "mypackage.MyClass.myMethod()").
* @since 5.3.5
* @see SmartApplicationListener#getListenerId()
* @see ApplicationEventMulticaster#removeApplicationListeners(Predicate)
*/
String id() default "";
}
https://github.com/spring-projects/spring-framework
GitHubSpring Framework. Contribute to spring-projects/spring-framework development by creating an account on GitHub.
https://github.com/KAMO030/kamo-core
GitHub基于原生jdk实现的一些小工具,可用来练习编程思维. Contribute to KAMO030/kamo-core development by creating an account on GitHub.
reactfx
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue.
Checklist
Describe the feature
计划新增 EventListener 注解,可以参照hutool是否有相应封装
Additional context
https://blog.csdn.net/qq_28051649/article/details/62216648