{"id":10008347,"date":"2023-09-27T23:21:16","date_gmt":"2023-09-27T15:21:16","guid":{"rendered":"https:\/\/blog.itmax.cn\/?p=10008347"},"modified":"2023-09-27T23:21:16","modified_gmt":"2023-09-27T15:21:16","slug":"%e6%8e%a2%e6%9e%90-spring-%e5%ae%b9%e5%99%a8%e5%86%85%e9%83%a8%e4%ba%8b%e4%bb%b6%e5%8f%91%e5%b8%83","status":"publish","type":"post","link":"https:\/\/itmax.cn\/?p=10008347","title":{"rendered":"\u63a2\u6790 Spring \u5bb9\u5668\u5185\u90e8\u4e8b\u4ef6\u53d1\u5e03"},"content":{"rendered":"<p>\u5176\u5b9e\u5728 JDK \u4e2d\u5df2\u7ecf\u63d0\u4f9b\u76f8\u5e94\u7684\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u53d1\u5e03\u529f\u80fd\u7684\u57fa\u7840\u7c7b:<\/p>\n<ul>\n<li><code>java.util.EventObject<\/code>\u7c7b \uff1a\u81ea\u5b9a\u4e49<strong>\u4e8b\u4ef6<\/strong>\u7c7b\u578b<\/li>\n<li><code>java.util.EventListener<\/code>\u63a5\u53e3\uff1a\u4e8b\u4ef6\u7684<strong>\u76d1\u542c\u5668<\/strong><\/li>\n<\/ul>\n<p>\u9996\u5148\u4e86\u89e3\u51e0\u4e2a\u6982\u5ff5\uff1a<br \/><img decoding=\"async\"   referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000044267785\" alt=\"image.png\" title=\"image.png\"><\/p>\n<h2>Spring \u4e8b\u4ef6\u7c7b\u7ed3\u6784<\/h2>\n<p><img decoding=\"async\"   referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000044267786\" alt=\"image.png\" title=\"image.png\" loading=\"lazy\"><\/p>\n<h3>1. \u4e8b\u4ef6\u7c7b<\/h3>\n<p>\u4e8b\u4ef6\u7c7b\u4e5f\u5c31\u662f\u5b9a\u4e49\u53d1\u9001\u7684\u5185\u5bb9\uff0c\u6bd4\u5982\u53ef\u4ee5\u901a\u8fc7\u7ee7\u627f<code>ApplicationContextEvent<\/code>\u6765\u81ea\u5b9a\u4e49\u4e00\u4e2a\u7279\u5b9a\u4e8b\u4ef6\u7c7b\u3002<br \/><img decoding=\"async\"   referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000044267787\" alt=\"image.png\" title=\"image.png\" loading=\"lazy\"><\/p>\n<h4>1.1 <code>ApplicationEvent<\/code>\u7c7b<\/h4>\n<p>\u9996\u5148\u662f\u7ee7\u627f <code>EventObject<\/code>\u7684<code>ApplicationEvent<\/code>\uff0c\u901a\u8fc7source\u6765\u6307\u5b9a\u4e8b\u4ef6\u6e90\uff1a<\/p>\n<pre><code class=\"java\">public abstract class ApplicationEvent extends EventObject {\n    \/**\n     * Constructs a prototypical Event.\n     *\n     * @param source The object on which the Event initially occurred.\n     * @throws IllegalArgumentException if source is null.\n     *\/\n    public ApplicationEvent(Object source) {\n        super(source);\n    }\n}<\/code><\/pre>\n<h4>1.2 <code>ApplicationContextEvent<\/code>\u7c7b<\/h4>\n<p>\u662f\u4e3b\u8981\u7684\u5bb9\u5668\u4e8b\u4ef6\uff0c\u5b83\u6709\u5bb9\u5668\u542f\u52a8\u3001\u5237\u65b0\u3001\u505c\u6b62\u4ee5\u53ca\u5173\u95ed\u5404\u79cd\u4e8b\u4ef6\u7684\u5b50\u7c7b\u3002<\/p>\n<pre><code class=\"java\">public class ApplicationContextEvent extends ApplicationEvent {\n\n    \/**\n     * Constructs a prototypical Event.\n     *\n     * @param source The object on which the Event initially occurred.\n     * @throws IllegalArgumentException if source is null.\n     *\/\n    public ApplicationContextEvent(Object source) {\n        super(source);\n    }\n\n    \/**\n     * Get the &lt;code&gt;ApplicationContext&lt;\/code&gt; that the event was raised for.\n     *\/\n    public final ApplicationContext getApplicationContext() {\n        return (ApplicationContext) getSource();\n    }\n\n}\n\npublic class ContextClosedEvent extends ApplicationContextEvent{\n\n    \/**\n     * Constructs a prototypical Event.\n     *\n     * @param source The object on which the Event initially occurred.\n     * @throws IllegalArgumentException if source is null.\n     *\/\n    public ContextClosedEvent(Object source) {\n        super(source);\n    }\n\n}\n\npublic class ContextRefreshedEvent extends ApplicationContextEvent{\n    \/**\n     * Constructs a prototypical Event.\n     *\n     * @param source The object on which the Event initially occurred.\n     * @throws IllegalArgumentException if source is null.\n     *\/\n    public ContextRefreshedEvent(Object source) {\n        super(source);\n    }\n\n}<\/code><\/pre>\n<p>\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u7ee7\u627f\u8be5\u7c7b\u6765\u5b9e\u73b0\uff0c\u7279\u5b9a\u7684\u4e8b\u4ef6\u7c7b\u578b\u9700\u6c42\uff0c\u6bd4\u5982\u8981\u5b9e\u73b0\u4e00\u4e2a\u90ae\u4ef6\u53d1\u9001\u4e8b\u4ef6\u3002\u53ea\u9700\u8981\u7ee7\u627f<code>ApplicationContextEvent<\/code>\u5373\u53ef\uff1a<\/p>\n<pre><code class=\"java\">public class MailSendEvent extends ApplicationContextEvent {\n    private String msg;\n\n    public MailSendEvent(Object source, String msg) {\n        super(source);\n        this.msg = msg;\n    }\n\n    public String getMsg() {\n        return msg;\n    }\n\n    public void setMsg(String msg) {\n        this.msg = msg;\n    }\n}<\/code><\/pre>\n<p>\u540c\u65f6<code>ApplicationContextEvent<\/code>\u4e5f\u6709\u7279\u5b9a\u7684\u51e0\u4e2a\u5b50\u7c7b\uff0c\u6765\u8868\u793a\u5bb9\u5668\u542f\u52a8\u3001\u5237\u65b0\u3001\u505c\u6b62\u4ee5\u53ca\u5173\u95ed\u4e8b\u4ef6\uff1a<br \/><img decoding=\"async\"   referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000044267788\" alt=\"image.png\" title=\"image.png\" loading=\"lazy\"><\/p>\n<h3>2.\u4e8b\u4ef6\u76d1\u542c\u5668<\/h3>\n<p>\u4e8b\u4ef6\u76d1\u542c\u5668\u63a5\u53e3\u4e2d\uff0c\u53ea\u5b9a\u4e49\u4e86\u4e00\u4e2a\u65b9\u6cd5\uff1a<code>onApplicationEvent(E event)<\/code>\u8be5\u65b9\u6cd5\u63a5\u6536<code>ApplicationEvent<\/code>\u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5728\u8be5\u65b9\u6cd5\u4e2d\u7f16\u5199\u4e8b\u4ef6\u7684\u54cd\u5e94\u5904\u7406\u903b\u8f91\u3002<\/p>\n<pre><code class=\"java\">public interface ApplicationListener&lt;E extends ApplicationEvent&gt; extends EventListener {\n\n    \/**\n     * \u63a5\u6536ApplicationEvent \u4e8b\u4ef6\u5bf9\u8c61\n     * \u5728\u8be5\u65b9\u6cd5\u4e2d\u7f16\u5199\u4e8b\u4ef6\u7684\u54cd\u5e94\u5904\u7406\u903b\u8f91\n     * @param event\n     *\/\n    void onApplicationEvent(E event);\n}<\/code><\/pre>\n<p>\u6211\u4eec\u540c\u6837\u4e5f\u53ef\u4ee5\u5b9e\u73b0\u8be5\u63a5\u53e3\u6765\u5b9e\u73b0\u7279\u5b9a\u7684\u4e8b\u4ef6\u76d1\u542c\u5668\u529f\u80fd\uff0c\u6bd4\u5982\u90ae\u4ef6\u53d1\u9001\u7684\u76d1\u542c\u5668\uff1a<\/p>\n<pre><code class=\"java\">public class MailSenderListener implements ApplicationListener&lt;MailSendEvent&gt; {\n\n    @Override\n    public void onApplicationEvent(MailSendEvent event) {\n        System.out.println(&quot;\u90ae\u4ef6\u53d1\u9001\u5668\u7684 resource:&quot; + event.getSource() + &quot;\u90ae\u4ef6\u53d1\u9001\u5668\u7684 msg:&quot; + event.getMsg());\n    }\n}<\/code><\/pre>\n<h3>3.\u4e8b\u4ef6\u5e7f\u64ad\u5668<\/h3>\n<p>\u4e8b\u4ef6\u5e7f\u64ad\u5668\u8d1f\u8d23\u5c06\u4e8b\u4ef6\u901a\u77e5\u76d1\u542c\u5668\u6ce8\u518c\u8868\u4e2d\u7684\u4e8b\u4ef6\u76d1\u542c\u5668\uff0c\u7136\u540e\u518d\u7531\u4e8b\u4ef6\u76d1\u542c\u5668\u5206\u522b\u5bf9\u4e8b\u4ef6\u8fdb\u884c\u54cd\u5e94\u3002Spring\u4e2d\u5b9a\u4e49\u4e86\u5982\u4e0b\u63a5\u53e3\uff1a<br \/><img decoding=\"async\"   referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000044267789\" alt=\"image.png\" title=\"image.png\" loading=\"lazy\"><\/p>\n<pre><code class=\"java\">public interface ApplicationEventMulticaster {\n\n    \/**\n     * \u6dfb\u52a0\u4e8b\u4ef6\u76d1\u542c\u5668\n     * @param listener\n     *\/\n    void addApplicationListener(ApplicationListener&lt;?&gt; listener);\n\n    \/**\n     * \u79fb\u9664\u4e8b\u4ef6\u76d1\u542c\u5668\n     * @param listener\n     *\/\n    void removeApplicationListener(ApplicationListener&lt;?&gt; listener);\n\n    \/**\n     * \u5e7f\u64ad\u4e8b\u4ef6\n     * @param event\n     *\/\n    void multicastEvent(ApplicationEvent event);\n}<\/code><\/pre>\n<p>\u53ca\u5176\u7b80\u5355\u5b9e\u73b0\u7c7b<code>SimpleApplicationEventMulticaster<\/code>\uff1a<\/p>\n<pre><code class=\"java\">public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster{\n\n    public SimpleApplicationEventMulticaster(BeanFactory beanFactory) {\n        setBeanFactory(beanFactory);\n    }\n    \/**unchecked \u8868\u793a\u544a\u8bc9\u7f16\u8bd1\u5668\u5ffd\u7565\u6307\u5b9a\u7684\u8b66\u544a\uff0c\u4e0d\u7528\u518d\u7f16\u8bd1\u5b8c\u6210\u540e\u51fa\u73b0\u8b66\u544a\u4fe1\u606f*\/\n    @SuppressWarnings(&quot;unchecked&quot;)\n    @Override\n    public void multicastEvent(ApplicationEvent event) {\n        for (ApplicationListener applicationListener : getApplicationListeners(event)) {\n            applicationListener.onApplicationEvent(event);\n        }\n    }\n}<\/code><\/pre>\n<h3>4.\u4e8b\u4ef6\u53d1\u5e03\u8005<\/h3>\n<p>\u5b83\u672c\u8eab\u4f5c\u4e3a\u4e8b\u4ef6\u6e90\uff0c\u4f1a\u5728\u5408\u9002\u7684\u65f6\u70b9\uff0c\u5c06\u76f8\u5e94\u4e8b\u4ef6\u53d1\u5e03\u7ed9\u5bf9\u5e94\u7684\u4e8b\u4ef6\u76d1\u542c\u5668\uff1a<\/p>\n<pre><code class=\"java\">public interface ApplicationEventPublisher {\n\n    \/**\n     * \u901a\u77e5\u76d1\u542c\u8005\u5e76\u53d1\u5e03\u4e8b\u4ef6\n     * @param event\n     *\/\n    void publishEvent(ApplicationEvent event);\n}<\/code><\/pre>\n<p>\u5728Spring\u5bb9\u5668\u4e8b\u4ef6\u4e2d\uff0c<code>ApplicationContext<\/code>\u63a5\u53e3\u5b9a\u4e49\u7ee7\u627f\u4e86<code>ApplicationEventPublisher<\/code>\u63a5\u53e3\uff0c\u6240\u4ee5\u5b9e\u9645\u4e0a<code>AbstractApplicationContext<\/code>\u5728\u4e8b\u4ef6\u4e2d\u627f\u62c5\u4e86\u4e8b\u4ef6\u53d1\u5e03\u8005\u7684\u89d2\u8272\u3002<br \/>\u4f46\u662f\u5728\u5b9e\u9645\u4e0a\u5177\u4f53\u5b9e\u73b0\u4e8b\u4ef6\u7684\u53d1\u5e03\u548c\u4e8b\u4ef6\u76d1\u542c\u5668\u6ce8\u518c\u65b9\u9762\uff0c\u5c06\u529f\u80fd\u8f6c\u63a5\u7ed9<code>ApplicationEventMulticaster<\/code>\u63a5\u53e3\uff0c\u6700\u7ec8\u5177\u4f53\u5b9e\u73b0\u5219\u653e\u5728<code>AbstractApplicationEventMulticaster<\/code>\u7684\u5b9e\u73b0\u7c7b\u4e2d\uff1a<br \/><img decoding=\"async\"   referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000044267790\" alt=\"image.png\" title=\"image.png\" loading=\"lazy\"><\/p>\n<h2>Spring \u4e8b\u4ef6\u7c7b\u7684\u5e94\u7528<\/h2>\n<p>\u90a3\u4e48\u5728Spring\u4e2d\uff0c\u4e8b\u4ef6\u7c7b\u5230\u5e95\u662f\u5982\u4f55\u8fd0\u884c\u7684\u5462\uff1f\u9996\u5148\u6211\u4eec\u4f1a\u5728xml\u914d\u7f6e\u6587\u4ef6\u4e2d\u914d\u7f6e\u76f8\u5e94\u7684<code>ApplicationListener<\/code>\u7c7b\u578b\u7684\u76d1\u542c\u5668\uff0c\u56e0\u6b64\u5728\u5bb9\u5668\u542f\u52a8\u540e\uff0c\u8fd9\u4e9b\u7c7b\u578b\u7684bean\u4f1a\u88ab<code>ApplicationContext<\/code>\u5bb9\u5668\u6240\u8bc6\u522b\uff0c\u5b83\u4eec\u8d1f\u8d23\u76d1\u542c\u5bb9\u5668\u5185\u53d1\u5e03\u7684\u5bf9\u5e94\u7684<code>ApplicationEvent<\/code>\u7c7b\u578b\u7684\u4e8b\u4ef6\u3002<\/p>\n<pre><code class=\"java\">&lt;bean class=&quot;cn.ethan.springframework.test.event.ContextRefreshedEventListener&quot;\/&gt;\n&lt;bean class=&quot;cn.ethan.springframework.test.event.MailSenderListener&quot;\/&gt;\n&lt;bean class=&quot;cn.ethan.springframework.test.event.ContextClosedEventListener&quot;\/&gt;<\/code><\/pre>\n<p>\u5728<code>AbstractApplicationContext<\/code>\u7684<code>refresh()<\/code>\u65b9\u6cd5\u4e2d\u53ef\u4ee5\u770b\u5230\u81ea\u52a8\u6ce8\u518c\u7684\u5185\u5bb9\uff1a<\/p>\n<pre><code class=\"java\">public void refresh() throws BeansException {\n\n        \/\/ 6. \u521d\u59cb\u5316\u4e8b\u4ef6\u53d1\u5e03\u8005\n        initApplicationEventMulticaster();\n\n        \/\/ 7. \u6ce8\u518c\u4e8b\u4ef6\u76d1\u542c\u5668\n        registerListeners();\n\n        \/\/ 9. \u53d1\u5e03\u5bb9\u5668\u5237\u65b0\u5b8c\u6210\u4e8b\u4ef6\n        finishRefresh();\n}\n\nprivate void initApplicationEventMulticaster() {\n    ConfigurableListableBeanFactory beanFactory = getBeanFactory();\n    applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);\n    beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, applicationEventMulticaster);\n}\n\nprivate void registerListeners() {\n    Collection&lt;ApplicationListener&gt; applicationListeners = getBeansOfType(ApplicationListener.class).values();\n    for (ApplicationListener listener : applicationListeners) {\n        applicationEventMulticaster.addApplicationListener(listener);\n    }\n}\n\nprivate void finishRefresh() {\n    publishEvent(new ContextRefreshedEvent(this));\n}\npublic void publishEvent(ApplicationEvent event) {\n    applicationEventMulticaster.multicastEvent(event);\n}<\/code><\/pre>\n<p>\u6240\u4ee5\u5728<code>ApplicationContext<\/code>\u5bb9\u5668\u542f\u52a8\u65f6\uff0c\u4f1a\u81ea\u52a8\u6ce8\u518c<code>EventListener<\/code>\u7c7b\u578b\u7684 Bean\uff0c\u4e00\u65e6\u68c0\u6d4b\u5230\u6709<code>ApplicationContextEvent<\/code>\u7c7b\u578b\u7684\u4e8b\u4ef6\u53d1\u5e03\uff0c\u5c06\u901a\u77e5\u8fd9\u4e9b\u6ce8\u518c\u5230\u5bb9\u5668\u7684<code>EventListener<\/code><\/p>\n<h3>\u5e94\u7528\u5b9e\u4f8b<\/h3>\n<p>\u4e0b\u9762\u5c06\u6784\u5efa\u4e00\u4e2a\u53d1\u9001\u90ae\u4ef6\u7684Spring\u4e8b\u4ef6\u5b9e\u4f8b\uff1a<\/p>\n<h4>1. \u90ae\u4ef6\u53d1\u9001\u4e8b\u4ef6<code>MailSendEvent<\/code><\/h4>\n<pre><code class=\"java\">public class MailSendEvent extends ApplicationContextEvent {\n    private String msg;\n\n    public MailSendEvent(Object source, String msg) {\n        super(source);\n        this.msg = msg;\n    }\n\n    public String getMsg() {\n        return msg;\n    }\n}<\/code><\/pre>\n<h4>2.\u90ae\u4ef6\u53d1\u9001\u4e8b\u4ef6\u76d1\u542c\u5668<code>MailSendListener<\/code>(\u90ae\u4ef6\u53d1\u9001\u4e8b\u4ef6)\u3001<code>ContextRefreshedEventListener<\/code>(\u5bb9\u5668\u5237\u65b0\u4e8b\u4ef6) \u548c <code>ContextClosedEventListener<\/code>(\u5bb9\u5668\u5173\u95ed\u4e8b\u4ef6)<\/h4>\n<pre><code class=\"java\">public class MailSenderListener implements ApplicationListener&lt;MailSendEvent&gt; {\n\n    @Override\n    public void onApplicationEvent(MailSendEvent event) {\n        System.out.println(&quot;\u90ae\u4ef6\u53d1\u9001\u5668\u7684 resource:&quot; + event.getSource() + &quot;\u90ae\u4ef6\u53d1\u9001\u5668\u7684 msg:&quot; + event.getMsg());\n    }\n}<\/code><\/pre>\n<pre><code class=\"java\">public class ContextClosedEventListener implements ApplicationListener&lt;ContextClosedEvent&gt; {\n\n    @Override\n    public void onApplicationEvent(ContextClosedEvent event) {\n        System.out.println(&quot;\u5173\u95ed\u4e8b\u4ef6\uff1a&quot; + this.getClass().getName());\n    }\n}<\/code><\/pre>\n<pre><code class=\"java\">public class ContextRefreshedEventListener implements ApplicationListener&lt;ContextRefreshedEvent&gt; {\n\n    @Override\n    public void onApplicationEvent(ContextRefreshedEvent event) {\n        System.out.println(&quot;\u5237\u65b0\/\u6253\u5f00\u4e8b\u4ef6\uff1a&quot; + this.getClass().getName());\n    }\n}<\/code><\/pre>\n<p>\u8fd9\u65f6\uff0c\u5c06\u76d1\u542c\u5668\u4eec\u6ce8\u5165xml\u6587\u4ef6\u4e2d\uff1a<\/p>\n<pre><code class=\"xml\">&lt;bean class=&quot;cn.ethan.springframework.test.event.ContextRefreshedEventListener&quot;\/&gt;\n&lt;bean class=&quot;cn.ethan.springframework.test.event.MailSenderListener&quot;\/&gt;\n&lt;bean class=&quot;cn.ethan.springframework.test.event.ContextClosedEventListener&quot;\/&gt;<\/code><\/pre>\n<h4>3.\u90ae\u4ef6\u53d1\u9001\u4e8b\u4ef6\u53d1\u5e03\u8005<\/h4>\n<p>\u4e8b\u4ef6\u53d1\u5e03\u8005<code>ApplicationEventPublisher<\/code>\uff0c\u56e0\u4e3a\u524d\u9762\u63d0\u5230\uff0c<code>applicationContext<\/code>\u7ee7\u627f\u4e86<code>ApplicationEventPublisher<\/code>\uff0c\u800c<code>applicationContext<\/code>\u5c06\u4e8b\u4ef6\u53d1\u5e03\u529f\u80fd\u59d4\u6258\u7ed9\u4e86<code>ApplicationEventMulticaster<\/code>\uff0c\u5bb9\u5668\u5728\u542f\u52a8\u5f00\u59cb\u5c31\u4f1a\u68c0\u67e5\u662f\u5426\u5b58\u5728\u540d\u79f0\u4e3a<code>applicationEventMulticaster<\/code>\u7684 <code>ApplicationEventMulticaster<\/code>\u5bf9\u8c61\u5b9e\u4f8b\uff0c\u5982\u679c\u6709\u5c31\u4f7f\u7528\u63d0\u4f9b\u7684\u5b9e\u73b0\uff0c\u6ca1\u6709\u5219\u9ed8\u8ba4\u521d\u59cb\u5316\u4e00\u4e2a<code>SimpleApplicationEventMulticaster<\/code>\u4f5c\u4e3a\u5c06\u4f1a\u4f7f\u7528\u7684<code>ApplicationEventMulticaster<\/code><\/p>\n<pre><code class=\"java\">\/**\n * @description: \u5b9e\u73b0\u4e86\u4e8b\u4ef6\u76d1\u542c\u5668\u7684\u7ba1\u7406\u529f\u80fd\n * @author: wjw\n * @date: 2022\/7\/9\n *\/\npublic abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster, BeanFactoryAware  {\n\n    public final Set&lt;ApplicationListener&lt;ApplicationEvent&gt;&gt; applicationListeners = new LinkedHashSet&lt;&gt;();\n\n    private BeanFactory beanFactory;\n\n    @Override\n    public void addApplicationListener(ApplicationListener&lt;?&gt; listener) {\n        applicationListeners.add((ApplicationListener&lt;ApplicationEvent&gt;) listener);\n    }\n\n    @Override\n    public void removeApplicationListener(ApplicationListener&lt;?&gt; listener) {\n        applicationListeners.remove(listener);\n    }\n\n    @Override\n    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {\n        this.beanFactory = beanFactory;\n    }\n\n    \/**\n     * \u83b7\u5f97\u76d1\u542c\u5668\n     * @param event\n     * @return\n     *\/\n    protected Collection&lt;ApplicationListener&gt; getApplicationListeners(ApplicationEvent event) {\n        LinkedList&lt;ApplicationListener&gt; allListeners = new LinkedList&lt;&gt;();\n        for (ApplicationListener&lt;ApplicationEvent&gt; listener : allListeners) {\n            if (supportsEvent(listener, event)) {\n                allListeners.add(listener);\n            }\n        }\n        return allListeners;\n    }\n\n    protected boolean supportsEvent(ApplicationListener&lt;ApplicationEvent&gt; applicationListener, ApplicationEvent event) {\n        Class&lt;? extends ApplicationListener&gt; listenerClass = applicationListener.getClass();\n\n        \/**\u6839\u636e\u4e0d\u540c\u5b9e\u4f8b\u5316\u7c7b\u578b\uff0c\u5224\u65ad\u540e\u83b7\u53d6\u5bf9\u5e94\u76ee\u6807 class*\/\n        Class&lt;?&gt; targetClass = ClassUtils.isCglibProxyClass(listenerClass) ? listenerClass.getSuperclass() : listenerClass;\n        Type genericInterface = targetClass.getGenericInterfaces()[0];\n\n        Type actualTypeArgument = ((ParameterizedType) genericInterface).getActualTypeArguments()[0];\n        String className = actualTypeArgument.getTypeName();\n        Class&lt;?&gt; eventClassName;\n        try {\n            eventClassName = Class.forName(className);\n        } catch (ClassNotFoundException e) {\n            throw new BeansException(&quot;wrong event class name: &quot; + className);\n        }\n\n        return eventClassName.isAssignableFrom(event.getClass());\n    }\n\n}<\/code><\/pre>\n<pre><code class=\"java\">public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster{\n\n    public SimpleApplicationEventMulticaster(BeanFactory beanFactory) {\n        setBeanFactory(beanFactory);\n    }\n    \/**unchecked \u8868\u793a\u544a\u8bc9\u7f16\u8bd1\u5668\u5ffd\u7565\u6307\u5b9a\u7684\u8b66\u544a\uff0c\u4e0d\u7528\u518d\u7f16\u8bd1\u5b8c\u6210\u540e\u51fa\u73b0\u8b66\u544a\u4fe1\u606f*\/\n    @SuppressWarnings(&quot;unchecked&quot;)\n    @Override\n    public void multicastEvent(ApplicationEvent event) {\n        for (ApplicationListener applicationListener : getApplicationListeners(event)) {\n            applicationListener.onApplicationEvent(event);\n        }\n    }\n}<\/code><\/pre>\n<h4>4.\u6d4b\u8bd5\u9a8c\u8bc1<\/h4>\n<pre><code class=\"java\">public void test_event() {\n    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(&quot;classpath:spring.xml&quot;);\n\n    applicationContext.publishEvent(new CustomEvent(applicationContext, 110L, &quot;test\uff01&quot;));\n\n    System.out.println(&quot;-----------------------------------------------------------------&quot;);\n    applicationContext.publishEvent(new MailSendEvent(applicationContext, &quot;\u90ae\u4ef6\u53d1\u9001\u6d4b\u8bd5&quot;));\n    applicationContext.registerShutdownHook();\n}<\/code><\/pre>\n<pre><code class=\"java\">\u5237\u65b0\/\u6253\u5f00\u4e8b\u4ef6\uff1acn.ethan.springframework.test.event.ContextRefreshedEventListener$$EnhancerByCGLIB$$2e5c458\n-----------------------------------------------------------------\n\u90ae\u4ef6\u53d1\u9001\u5668\u7684 resource:cn.ethan.springframework.context.support.ClassPathXmlApplicationContext@5f2050f6\u90ae\u4ef6\u53d1\u9001\u5668\u7684 msg:\u90ae\u4ef6\u53d1\u9001\u6d4b\u8bd5\n\u5173\u95ed\u4e8b\u4ef6\uff1acn.ethan.springframework.test.event.ContextClosedEventListener$$EnhancerByCGLIB$$fbc2c978\n<\/code><\/pre>\n<p><a href=\"https:\/\/segmentfault.com\/a\/1190000044267783\">https:\/\/segmentfault.com\/a\/1190000044267783<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u5176\u5b9e\u5728 JDK \u4e2d\u5df2\u7ecf\u63d0\u4f9b\u76f8\u5e94\u7684\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u53d1\u5e03\u529f\u80fd\u7684\u57fa\u7840\u7c7b: java.util.EventObject\u7c7b \uff1a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[4],"tags":[],"class_list":["post-10008347","post","type-post","status-publish","format-standard","hentry","category-share"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts\/10008347","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=10008347"}],"version-history":[{"count":0,"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts\/10008347\/revisions"}],"wp:attachment":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10008347"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=10008347"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=10008347"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}