• 后端简易实验框架


    引子

    后端开发时,常常需要启动应用,将应用中所需的 bean 实例化并注入依赖 OK,而后验证一些新功能。一般的做法是,启动应用后,通过工具或 Curl 命令发送请求来触发 API 接口。有时,要验证的功能不一定通过 API 接口透漏出去,而是内部的业务逻辑。此时,要验证这些业务逻辑,不得不额外开发一些接口来触发调用。这样不够经济。

    可以采用一些方法,在 Spring 容器正常启动,且将 bean 实例化并注入依赖 OK 后,自动运行一些实验代码,在实验代码里调用所要验证的服务业务逻辑。

    实验框架

    定义实验接口

    定义实验接口: IExperiment.java

    public interface IExperiment {
        void test();
    }
    

    编写一个实验类

    InsertOrderExperiment.java

    @Component
    public class InsertOrderExperiment implements IExperiment {
    
        private static Log log = LogFactory.getLog(InsertOrderExperiment.class);
    
        @Resource
        OrderMapper orderMapper;
    
        @Override
        public void test() {
    
            OrderDO orderDO = new OrderDO();
            orderDO.setOrderNo("E202009010000001234000003");
            orderDO.setUserId(123245L);
            orderDO.setShopId(654321L);
            orderDO.setState(1);
            orderDO.setDeliveryType(DeliveryType.express.getCode());
            orderDO.setPrice(100L);
            orderDO.setPayWay(PayWay.wxpay.getCode());
            orderDO.setBookTime(1609556430L);
            Map map = new HashMap<>();
            map.put("expressFee", 10L);
            orderDO.setExtend(JSON.toJSONString(map));
            Integer insertId = orderMapper.insert(orderDO);
            log.info("Order InsertId: " + insertId);
    
    
        }
    }
    

    自动加载实验

    Experiments.java

    
    @Component
    public class Experiments implements ApplicationListener<ContextRefreshedEvent>, ApplicationContextAware {
    
        private ApplicationContext applicationContext;
    
        @Override
        public void onApplicationEvent(ContextRefreshedEvent event) {
            doExperiments();
        }
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
        }
    
        private void doExperiments() {
            Map<String, IExperiment> experiments = applicationContext.getBeansOfType(IExperiment.class);
            experiments.forEach(
                    (key, value) -> {
                        value.test();
                    }
            );
        }
    }
    
    

    ContextRefreshedEvent原理

    为什么实现了 ApplicationListener<ContextRefreshedEvent> 会在 context freshed 之后自动调用 onApplicationEvent 方法呢?

    ContextRefreshedEvent发布

    在 AbstractApplicationContext.java 的 refresh 方法中调用了 finishRefresh 方法:

    
            protected void finishRefresh() {
    		// Initialize lifecycle processor for this context.
    		initLifecycleProcessor();
    
    		// Propagate refresh to lifecycle processor first.
    		getLifecycleProcessor().onRefresh();
    
    		// Publish the final event.
    		publishEvent(new ContextRefreshedEvent(this));
    
    		// Participate in LiveBeansView MBean, if active.
    		LiveBeansView.registerApplicationContext(this);
    	}
    
            protected void publishEvent(Object event, ResolvableType eventType) {
    		Assert.notNull(event, "Event must not be null");
    		if (logger.isTraceEnabled()) {
    			logger.trace("Publishing event in " + getDisplayName() + ": " + event);
    		}
    
    		// Decorate event as an ApplicationEvent if necessary
    		ApplicationEvent applicationEvent;
    		if (event instanceof ApplicationEvent) {
    			applicationEvent = (ApplicationEvent) event;
    		}
    		else {
    			applicationEvent = new PayloadApplicationEvent<Object>(this, event);
    			if (eventType == null) {
    				eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType();
    			}
    		}
    
    		// Multicast right now if possible - or lazily once the multicaster is initialized
    		if (this.earlyApplicationEvents != null) {
    			this.earlyApplicationEvents.add(applicationEvent);
    		}
    		else {
    			getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
    		}
    
    		// Publish event via parent context as well...
    		if (this.parent != null) {
    			if (this.parent instanceof AbstractApplicationContext) {
    				((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
    			}
    			else {
    				this.parent.publishEvent(event);
    			}
    		}
    	}
    
    

    触发监听器

    
            @Override
    	public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
    		ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    		for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
    			Executor executor = getTaskExecutor();
    			if (executor != null) {
    				executor.execute(new Runnable() {
    					@Override
    					public void run() {
    						invokeListener(listener, event);
    					}
    				});
    			}
    			else {
    				invokeListener(listener, event);
    			}
    		}
    	}
    
            private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
    		try {
    			listener.onApplicationEvent(event);    // 调用 onApplicationEvent 方法
    		}
    		catch (ClassCastException ex) {
    			// code for handling exception
    		}
    	}
    
    

  • 相关阅读:
    3.3 x86指令简介
    8.2 DRAM和SRAM
    7.2 流水线的优化
    8.3 主存的工作原理
    matlab练习程序(ACF/PACF系数计算)
    Github——常用命令介绍
    Mac上永久修改默认Python版本
    FIO – IO压力测试工具 规格严格
    postgresqlco.nf 规格严格
    pg9.6单纯写性能探索 规格严格
  • 原文地址:https://www.cnblogs.com/lovesqcc/p/14232861.html
Copyright © 2020-2023  润新知