当前位置: 首页 > news >正文

深圳工厂网站建设公司一个人做网站现实吗

深圳工厂网站建设公司,一个人做网站现实吗,免费咨询肺部医生在线,捕鱼网站怎么做背景在开发工作中#xff0c;会遇到一种场景#xff0c;做完某一件事情以后#xff0c;需要广播一些消息或者通知#xff0c;告诉其他的模块进行一些事件处理#xff0c;一般来说#xff0c;可以一个一个发送请求去通知#xff0c;但是有一种更好的方式#xff0c;那就… 背景在开发工作中会遇到一种场景做完某一件事情以后需要广播一些消息或者通知告诉其他的模块进行一些事件处理一般来说可以一个一个发送请求去通知但是有一种更好的方式那就是事件监听事件监听也是设计模式中发布-订阅模式、观察者模式的一种实现。观察者模式简单的来讲就是你在做事情的时候身边有人在盯着你当你做的某一件事情是旁边观察的人感兴趣的事情的时候他会根据这个事情做一些其他的事但是盯着你看的人必须要到你这里来登记否则你无法通知到他或者说他没有资格来盯着你做事情。对于Spring容器的一些事件可以监听并且触发相应的方法。通常的方法有 2 种ApplicationListener 接口和EventListener 注解。简介要想顺利的创建监听器并起作用这个过程中需要这样几个角色事件event可以封装和传递监听器中要处理的参数如对象或字符串并作为监听器中监听的目标。监听器listener具体根据事件发生的业务处理模块这里可以接收处理事件中封装的对象或字符串。事件发布者publisher事件发生的触发者。ApplicationListener 接口ApplicationListener接口的定义如下它是一个泛型接口泛型的类型必须是ApplicationEvent 及其子类只要实现了这个接口那么当容器有相应的事件触发时就能触发 onApplicationEvent 方法。ApplicationEvent 类的子类有很多Spring 框架自带的如下几个。▐  简单使用使用方法很简单就是实现一个 ApplicationListener 接口并且将加入到容器中就行。Component public class DefinitionApplicationListener implements ApplicationListenerApplicationEvent {// ----------- 简单使用-实现ApplicationListener 接口Overridepublic void onApplicationEvent(ApplicationEvent event) {System.out.println(事件触发:  event.getClass().getName());} }启动项目SpringBootApplication public class EngineSupportApplication {public static void main(String[] args) {SpringApplication.run(EngineSupportApplication.class);} }查看日志2021-11-12 21:04:16.114  INFO 83691 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService applicationTaskExecutor 事件触发:org.springframework.context.event.ContextRefreshedEvent 2021-11-12 21:04:16.263  INFO 83691 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path  事件触发:org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent 2021-11-12 21:04:16.266  INFO 83691 --- [           main] com.alibaba.EngineSupportApplication     : Started EngineSupportApplication in 1.975 seconds (JVM running for 3.504) 事件触发:org.springframework.boot.context.event.ApplicationStartedEvent 事件触发:org.springframework.boot.context.event.ApplicationReadyEvent自定义事件以及监听▐ 定义事件public class DefinitionEvent extends ApplicationEvent {public boolean enable;/*** Create a new ApplicationEvent.** param source the object on which the event initially occurred (never {code null})* param enable*/public DefinitionEvent(Object source, boolean enable) {super(source);this.enable  enable;}▐ 定义监听器Component public class DefinitionApplicationListener implements ApplicationListenerApplicationEvent {// ----------- 简单使用-实现ApplicationListener 接口Overridepublic void onApplicationEvent(ApplicationEvent event) {System.out.println(事件触发:  event.getClass().getName());}// ----------- 自定义事件以及监听Autowiredprivate ApplicationEventPublisher eventPublisher;/*** 事件发布方法*/public void pushListener(String msg) {eventPublisher.publishEvent(new DefinitionEvent(this, false));} }EventListener 注解▐ 简单使用除了通过实现接口还可以使用EventListener 注解实现对任意的方法都能监听事件。在任意方法上标注EventListener 注解指定 classes即需要处理的事件类型一般就是 ApplicationEvent及其子类可以设置多项。Component public class DefinitionAnnotationEventListener {EventListener(classes  {DefinitionEvent.class})public void listen(DefinitionEvent event) {System.out.println(注解监听器  event.getClass().getName());}}此时就可以有一个发布两个监听器监听到发布的消息了一个是注解方式一个是非注解方式结果注解监听器com.alibaba.spring.context.event.DefinitionEvent 事件触发:com.alibaba.spring.context.event.DefinitionEvent原理其实上面添加EventListener注解的方法被包装成了ApplicationListener对象上面的类似于下面这种写法这个应该比较好理解。Component public class DefinitionAnnotationEventListener implements ApplicationListenerDefinitionEvent {Overridepublic void onApplicationEvent(DefinitionEvent event) {System.out.println(注解监听器:  event.getMsg());} }查看SpringBoot的源码找到下面的代码,因为我是Tomcat环境这里创建的ApplicationContext是org.springframework.bootweb.servlet.context.AnnotationConfigServletWebServerApplicationContextprotected ConfigurableApplicationContext createApplicationContext() {Class? contextClass  this.applicationContextClass;if (contextClass  null) {try {switch (this.webApplicationType) {case SERVLET:contextClass  Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);break;case REACTIVE:contextClass  Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);break;default:contextClass  Class.forName(DEFAULT_CONTEXT_CLASS);}}catch (ClassNotFoundException ex) {throw new IllegalStateException(Unable create a default ApplicationContext,   please specify an ApplicationContextClass,ex);}}return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);}构造方法如下public AnnotationConfigApplicationContext() {this.reader  new AnnotatedBeanDefinitionReader(this);this.scanner  new ClassPathBeanDefinitionScanner(this); }进入AnnotatedBeanDefinitionReader里面/*** Create a new {code AnnotatedBeanDefinitionReader} for the given registry,* using the given {link Environment}.* param registry the {code BeanFactory} to load bean definitions into,* in the form of a {code BeanDefinitionRegistry}* param environment the {code Environment} to use when evaluating bean definition* profiles.* since 3.1*/public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {Assert.notNull(registry, BeanDefinitionRegistry must not be null);Assert.notNull(environment, Environment must not be null);this.registry  registry;this.conditionEvaluator  new ConditionEvaluator(registry, environment, null);AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);}再进到AnnotationConfigUtils的方法里面省略了一部分代码可以看到他注册了一个EventListenerMethodProcessor类到工厂了。这是一个BeanFactory的后置处理器。public static SetBeanDefinitionHolder registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, Nullable Object source) {DefaultListableBeanFactory beanFactory  unwrapDefaultListableBeanFactory(registry);.................    if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def  new RootBeanDefinition(EventListenerMethodProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));}............return beanDefs;}查看这个BeanFactory的后置处理器EventListenerMethodProcessor下面方法他会遍历所有bean找到其中带有EventListener的方法将它包装成ApplicationListenerMethodAdapter注册到工厂里这样就成功注册到Spring的监听系统里了。Overridepublic void afterSingletonsInstantiated() {ConfigurableListableBeanFactory beanFactory  this.beanFactory;Assert.state(this.beanFactory ! null, No ConfigurableListableBeanFactory set);String[] beanNames  beanFactory.getBeanNamesForType(Object.class);for (String beanName : beanNames) {if (!ScopedProxyUtils.isScopedTarget(beanName)) {Class? type  null;try {type  AutoProxyUtils.determineTargetClass(beanFactory, beanName);}catch (Throwable ex) {// An unresolvable bean type, probably from a lazy bean - lets ignore it.if (logger.isDebugEnabled()) {logger.debug(Could not resolve target class for bean with name   beanName  , ex);}}if (type ! null) {if (ScopedObject.class.isAssignableFrom(type)) {try {Class? targetClass  AutoProxyUtils.determineTargetClass(beanFactory, ScopedProxyUtils.getTargetBeanName(beanName));if (targetClass ! null) {type  targetClass;}}catch (Throwable ex) {// An invalid scoped proxy arrangement - lets ignore it.if (logger.isDebugEnabled()) {logger.debug(Could not resolve target bean for scoped proxy   beanName  , ex);}}}try {processBean(beanName, type);}catch (Throwable ex) {throw new BeanInitializationException(Failed to process EventListener  annotation on bean with name   beanName  , ex);}}}}}private void processBean(final String beanName, final Class? targetType) {if (!this.nonAnnotatedClasses.contains(targetType) !targetType.getName().startsWith(java) !isSpringContainerClass(targetType)) {MapMethod, EventListener annotatedMethods  null;try {annotatedMethods  MethodIntrospector.selectMethods(targetType,(MethodIntrospector.MetadataLookupEventListener) method -AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class));}catch (Throwable ex) {// An unresolvable type in a method signature, probably from a lazy bean - lets ignore it.if (logger.isDebugEnabled()) {logger.debug(Could not resolve methods for bean with name   beanName  , ex);}}if (CollectionUtils.isEmpty(annotatedMethods)) {this.nonAnnotatedClasses.add(targetType);if (logger.isTraceEnabled()) {logger.trace(No EventListener annotations found on bean class:   targetType.getName());}}else {// Non-empty set of methodsConfigurableApplicationContext context  this.applicationContext;Assert.state(context ! null, No ApplicationContext set);ListEventListenerFactory factories  this.eventListenerFactories;Assert.state(factories ! null, EventListenerFactory List not initialized);for (Method method : annotatedMethods.keySet()) {for (EventListenerFactory factory : factories) {if (factory.supportsMethod(method)) {Method methodToUse  AopUtils.selectInvocableMethod(method, context.getType(beanName));ApplicationListener? applicationListener factory.createApplicationListener(beanName, targetType, methodToUse);if (applicationListener instanceof ApplicationListenerMethodAdapter) {((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator);}context.addApplicationListener(applicationListener);break;}}}if (logger.isDebugEnabled()) {logger.debug(annotatedMethods.size()   EventListener methods processed on bean  beanName  :   annotatedMethods);}}}}由方法生成Listener的逻辑由EventListenerFactory完成的这又分为两种一种是普通的EventLintener另一种是TransactionalEventListener是由两个工厂处理的。总结上面介绍了EventListener的原理其实上面方法里还有一个TransactionalEventListener注解其实原理是一模一样的只是这个监听者可以选择在事务完成后才会被执行事务执行失败就不会被执行。这两个注解的逻辑是一模一样的并且TransactionalEventListener本身就被标记有EventListener只是最后生成监听器时所用的工厂不一样而已。往期推荐MyBatis 中为什么不建议使用 where 11MyBatis原生批量插入的坑与解决方案聊聊sql优化的15个小技巧
http://www.pierceye.com/news/862916/

相关文章:

  • dede网站后台合肥网站建设行情
  • 做动漫网站侵权吗途牛网网站建设评价
  • 域名到期对网站的影响做美缝在哪个网站接单
  • 网站建设技术网站刚做网站和搜出来的不一样
  • 营销型网站建设集装箱液袋如何做做网站
  • 刘晓忠 网站建设手机网站绑定域名是什么意思
  • 东莞网站建设 包装材料汅app下载大全2022
  • 湖南平台网站建设找哪家设计师培训班多少钱
  • 网站代码素材重庆渝发建设有限公司官网
  • 网站标题能改吗加强档案网站建设
  • 2016网站设计龙岩微信网站建设
  • 梅州建站规划网站建设从零到精通.pdf
  • 商业机构的网址网站关键词优化费用
  • 企业网站建设中期报告模板微信小程序开发需要哪些技术
  • 裕顺网站建设上海房价2022年最新房价
  • 百度联盟做网站赚钱制作网页完整步骤
  • 化妆品网站建设规划书范文h5网站建设h
  • 增城低价网站建设app制作公司哪个好
  • 网站建设制作苏州自己做网站能赚钱吗2018
  • 太原做手机网站临沂外贸网站
  • 哪个域名注册网站好下载爱南宁乘车
  • 网站备案接入商是什么交互设计个人网站
  • 移动 网站模板app推广视频
  • 网站网页设计中怎么添加页码信息wordpress中文包
  • 网站优化排名软件网怎么看网站服务器地址
  • iis网站建设中怎么免费做网站不要域名
  • 广州 网站开发 公司怎样做一个公众号
  • 注册网站域名需要什么河南网站建设定制
  • 白种女人做爰网站网站建设新闻动态
  • 360百度网站怎么做徐州企业建站模板