Spring中观察者模式的应用

Spring中观察者模式的应用

Spring里的ApplicationListen相当于观察者;ApplicationEventPublisher可看作被观察对象。
当需要实现通知多个观察者的操作时可使用Spring里的ApplicationEventPublishe。观察者的操作可同步也可异步。

@Service
public class MyService {
    /**
     * Spring4.2之后,ApplicationEventPublisher 自动被注入到容器中,不再需要显示实现Aware接口。
     */
    @Autowired
    private ApplicationEventPublisher publisher;

    public void doSomething(){
        System.out.println(Thread.currentThread().getName()+ ":send the msg");
        //发布通知
        publisher.publishEvent(new MyEvent("content"));
    }
}
/**
 * 自定义事件
 */
public class MyEvent extends ApplicationEvent {
    public MyEvent(Object source) {
        super(source);
    }
}
/**
 * 自定义监听器(观察者)
 */
@Component
public class MyListener   {
    @EventListener
    public void reciveMsg(MyEvent myEvent){
        String msg = (String) myEvent.getSource();
        System.out.println(Thread.currentThread().getName()+ ": recive msg --"+msg);
    }
}

运行结果:service调用publisher的publishEven方法会将ApplicationEvent对象传给Multicast对象,Multicast对象可以根据ApplicationEvent拿到对应的监听器集合,迭代这个集合,执行每个监听器的操作。 这个过程是同步的,也就是说service必须等待观察者操作完毕才能继续运行。
当需要观察者异步执行时可做以下修改:
在容器中添加一个自定义的Executor,在启动类上添加@EnableAsync注解

@Configuration
@ComponentScan
@EnableAsync
public class MyConfig {
    @Bean("myThreadPool")
    public Executor getExecutor() {
        ThreadFactory namedThreadFactory = r -> {
            Thread thread = new Thread(r);
            thread.setName("myThreadPool");
            return thread;
        };
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 线程池维护线程的最少数量
        executor.setCorePoolSize(5);
        // 线程池维护线程的最大数量
        executor.setMaxPoolSize(10);
        // 缓存队列
        executor.setQueueCapacity(25);
        //线程名
        executor.setThreadFactory(namedThreadFactory);
        // 线程池初始化
        executor.initialize();
        return executor;
    }
}

在监听器方法上添加@Async注解,指定自己定义的Executor

/**
 * 自定义监听器(观察者)
 */
@Component
public class MyListener   {
    @Async("myThreadPool")
    @EventListener
    public void reciveMsg(MyEvent myEvent){
        String msg = (String) myEvent.getSource();
        System.out.println(Thread.currentThread().getName()+ ": recive msg --"+msg);
    }
}
发布了16 篇原创文章 · 获赞 0 · 访问量 171

猜你喜欢

转载自blog.csdn.net/qq_41738264/article/details/105556324