您的位置:澳门皇家娱乐场 > 澳门皇家娱乐场 > spring事件传播,开拓技术员必会的Linux命令

spring事件传播,开拓技术员必会的Linux命令

发布时间:2019-10-06 05:29编辑:澳门皇家娱乐场浏览(75)

    实现 ApplicationContextAware接口

    public final class SpringContextHolder implements ApplicationContextAware { private static ApplicationContext springContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringContextHolder.springContext = applicationContext; } /** * 返回spring上下文环境对象 * * @return ApplicationContext */ public static ApplicationContext getSpringContext() { return springContext; } /** * 发布事件到spring * @param event */ public static void pushEvent(ApplicationEvent event) { springContext.publishEvent; }}
    

    可选:仍可以在xml配置下方便使用

    <bean ></bean>
    
    五、InheritableThreadLocal的弊端

    InheritableThreadLocal的坏处也很显然,正是不可能达成池化父子线程之间数据的传递。就算大家明天要做一个布满式链路监察和控制系统,想借助线程独立副本变量来做,就必须求夺回那几个困难,因为在线程池大行其道的时代,随意贰个框架都用了种种线程池。幸运的是,前些天临时发掘Ali提供了那么些难题的缓慢解决方案,那就是transmittable-thread-local.想深刻商讨的爱侣,能够去github看它的源码。比较晚了,这里就不开展了,后一次在细讲transmittable-thread-local。

    仿效文书档案:

    • 翻看端口使用状态netstat -tln

    • 查看钦点端口使用状态netstat -ano | grep 2181 //查看2181端口使用情况

    • 查看占用内定端口的长河sudo lsof -i :2181 //查看2181端口被哪些进度占用

    public class Author { private List<AuthorName> names; public List<AuthorName> getNames() { return names; } public void setNames(List<AuthorName> names) { this.names = names; } public void addAuthorName(AuthorName name) { if (name == null) { return; } if (this.names == null) { this.names = new ArrayList<>(); } this.names.add; }}
    

    但实际static功用是怎么样了?

    实现ApplicationListener

    @Componentpublic class SendSmsEventListener implements ApplicationListener<SendSmsEvent> { @Resource private ISmsLogService smsLogServiceImpl; private final Logger logger = LoggerFactory.getLogger(SendSmsEventListener.class); @Resource private ISmsSender yunPianSmsSender; /** * @param smsLog status 0成功,非0失败 */ @Override @Async public void onApplicationEvent(SendSmsEvent event) { SmsLog smsLog = event.getSmsSource(); CallResult result = yunPianSmsSender.send(smsLog.getSmsText(), smsLog.getUserPhone; smsLog.setSendStatus(result.getStatus; smsLog.setSendTime(new Date; if (event.isPersistent { try { smsLogServiceImpl.save; } catch (Exception e) { logger.error("发送短信出" + e.getMessage; } } }}
    
    需求:

    longTimeMethod()方法是一个耗费时间艺术,所以要思考把它作成异步服务.比方:

     new Thread(new Callable<Integer>(){ public Integer call(){ return longTimeMethod.start();
    

    不过如此做就汇合世三个题材:因为spring的事体是选用ThreadLocal来做的,若是在事情方法中单独再起三个线程去运维其他四个劳务,则别的贰个劳动就得到不到原本的业务,所以只好把longTimeMethod()单独作成三个政工服务来运营.

    • 翻看CPU使用率、内部存款和储蓄器、虚构内部存款和储蓄器交流情形、IO读写景况vmstat 5 //每5秒刷新一回

    • 查阅系统中相继进度的能源占用现象top //使用top命令后,按Shift+M, 展现结果将遵循进度内部存款和储蓄器占用率排序

    • 查看内存使用情状free -m //以MB为单位

    • 翻看磁盘空间使用情形df -h

    public class Test2 { public static Books readBooks(File xmlPath, Class<?> XmlClazz) throws IOException, SAXException { Digester digester = getLoader.newDigester(); return digester.parse; } public static DigesterLoader getLoader(final Class<?> XmlClazz) { return newLoader(new FromAnnotationsRuleModule() { @Override protected void configureRules() { bindRulesFrom; } }); } public static void main(String[] args) throws IOException, SAXException { String baseDir = System.getProperty("user.dir"); File xmlFile = new File(baseDir + "/src/main/resources/books.xml"); Books books = readBooks(xmlFile, Books.class); }}
    

    至于Java关键字static静态修饰符,大家都很熟练。

    测试

    package com.ghgcn.event.test;import com.ghgcn.event.service.DemoEvent;import com.ghgcn.event.service.DemoPulisher;import com.ghgcn.event.service.EventConfig;import org.springframework.context.annotation.AnnotationConfigApplicationContext;import java.util.Date;public class EventTest { public static void main(String [] args){ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(EventConfig.class); DemoPulisher demoPulisher = context.getBean(DemoPulisher.class); demoPulisher.publish(new DemoEvent(new Date(),"魂牵梦萦 ")); context.close(); }}
    
    17:46:26.821 [main] DEBUG org.springframework.core.env.PropertySourcesPropertyResolver - Could not find key 'spring.liveBeansView.mbeanDomain' in any property source. Returning [null]17:46:26.822 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'demoPulisher'17:46:26.823 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'demoEventListener'17:46:26.823 [main] DEBUG com.ghgcn.event.service.DemoEventListener - onApplicationEvent DemoEvent{msg='魂牵梦萦 ', source=Thu Oct 26 17:46:26 CST 2017}17:46:26.824 [main] DEBUG com.ghgcn.event.service.DemoEventListener - onApplicationEvent DemoEvent{msg='魂牵梦萦 ', source=Thu Oct 26 17:46:26 CST 2017}17:46:26.825 [main] DEBUG com.ghgcn.event.service.DemoEventListener - onApplicationEvent DemoEvent{msg='魂牵梦萦 ', source=Thu Oct 26 17:46:26 CST 2017}17:46:26.825 [main] DEBUG com.ghgcn.event.service.DemoEventListener - onApplicationEvent DemoEvent{msg='魂牵梦萦 ', source=Thu Oct 26 17:46:26 CST 2017}17:46:26.825 [main] DEBUG com.ghgcn.event.service.DemoEventListener - onApplicationEvent DemoEvent{msg='魂牵梦萦 ', source=Thu Oct 26 17:46:26 CST 2017}17:46:26.825 [main] DEBUG com.ghgcn.event.service.DemoEventListener - onApplicationEvent DemoEvent{msg='魂牵梦萦 ', source=Thu Oct 26 17:46:26 CST 2017}17:46:26.825 [main] DEBUG com.ghgcn.event.service.DemoEventListener - onApplicationEvent DemoEvent{msg='魂牵梦萦 ', source=Thu Oct 26 17:46:26 CST 2017}17:46:26.825 [main] DEBUG com.ghgcn.event.service.DemoEventListener - onApplicationEvent 魂牵梦萦 DemoEventListener 接收到的消息 DemoEvent{msg='魂牵梦萦 ', source=Thu Oct 26 17:46:26 CST 2017}
    
    一、引言

    显著,ThreadLocal是java开辟中不能缺少的关键类,并且它在十二线程碰着下能表达十分重要的作用。它的囤积结构类似于Map<Thread,Object>,正是以当下线程作为Key的四个Map.所以差别线程之间能做到能源独立,不设有并发访谈的标题。由于市道上很多讲ThreadLocal源码的稿子,作者这里就不再赘述了,小编相信绝大多数的童鞋随意花点时间就能够领略。

    • 基于名称查询进度ps -ef | grep java //使用正式格式呈现ps aux | grep java //使用BSD的格式展现

    • 干掉进度kill -9 pid //pid为对应的进程号

    正文提供三种将XML映射成Java对象的办法,分别是选择评释和是不应用评释。

    在Java程序里面,所有的事物都以目的,而指标的抽象正是类,对于贰个类来讲,即便要动用她的分子或格局,那么平常意况下必得先实例化对象后,通过对象的引用技巧够访问这么些分子或措施,不过有种情景各异,就是该成员是用static表明的,就能够援引成员或方式。最大旨的有Integer.parseInt(),Float.parseFloat()等等用来把对象转变为所急需的骨干数据类型,那样的变量和方法我们又叫做类变量和类措施。

    相似情况下,假若略微代码必需在品种运营的时候就实践的时候,供给动用静态代码块,这种代码是前赴后继推行的

    须要在档期的顺序运行的时候就开端化,在不创设对象的事态下,别的程序来调用的时候,供给利用静态方法,这种代码是无所作为实施的. 静态方法在类加载的时候 就已经加载 能够用类名直接调用例如main方法就必需是静态的 那是前后相继入口两个的差别正是:静态代码块是电动实施的;静态方法是被调用的时候才实践的.

    PS: 三个对象的发轫化顺序

    推行Parent类的静态代码块 -- >Parent类的非静态代码块试行达成-- > 接着实行Parent类的构造方法

    图片 1

    亟待明白2个概念:

    1)首先,用在那之中类是因为中间类与各省外界类有一定的关系,往往唯有该外界类调用此个中类。所以无需特地用三个Java文件贮存这一个类。

    2)静态内部类也叫嵌套类,用这几个名字给他定义是更加的形象的。意思是说内部类和表面类的关联只是档次嵌套关系,所以只是在创制类公事的时候类公事名是之类形式:outer$inner.java,在采用方面统统和五个普通类同样

    作用:

    1)静态内部类的成效:只是为着收缩包的深浅,方便类的行使,静态内部类适用于含有类在那之中,但又不依据与外在的类,不用选取外在类的非静态属性和措施,只是为了便于管理类结构而定义。在创造静态内部类的时候,无需外界类对象的引用。

    深入显出的讲:比方有A,B多少个类,B有一些特别,即便能够单独存在,但只被A使用。固然把B并入A里,复杂度升高,搞得A违反单一职责。若是B独立,又或然被别的类(例如同多个包下的C)信任,不相符规划的本心。所以不及将其形成A.B,等于加多个注释,告诉其余类型使用B了,它只跟A玩。

    2)非静态内部类才是确实的内部类:可以放肆使用外界类的有所变量和章程

    静态导包正是java包的静态导入,用import static替代import静态导入包。

    spring事件传播,开拓技术员必会的Linux命令。平时大家导入贰个类都用 import com…..ClassName;而静态导入是那样:import static com…..ClassName.*;这里的多了个static,还或然有正是类名ClassName前面多了个.* ,意思是导入这么些类里的静态方法。当然,也足以只导入有些静态方法,只要把 .* 换来静态方法名就行了。然后在那一个类中,就能够直接用艺术名调用静态方法,而毋庸用ClassName.方法名 的措施来调用。

    优点:能够简化一些操作,比方打字与印刷操作System.out.println;就足以将其写入叁个静态方法print,在运用时直接print就能够了。

    发送者

    @Componentpublic class DemoPulisher { @Autowired ApplicationContext applicationContext; public void publish(ApplicationEvent applicationEvent){ //applicationContext.publishEvent(applicationEvent); applicationContext.publishEvent(applicationEvent); }}
    
    四、谈谈InheritableThreadLocal

    我们后边已经讲到ThreadLocal有跨进程的主题素材,约等于线程A的线程独立别本对于新创立的线程B不可知。可是为了把线程A的独自别本传递给子线程来兑现更头晕目眩的必要,JDK就贯彻了InheritableThreadLocal。InheritableThreadLocal承继自ThreadLocal,覆盖了ThreadLocal的getMap和createMap方法。它又是怎么落到实处线程之间数据的传递的吗?上面大家来讲说。

    1. 先来看下Thread类中的成员变量
     /* ThreadLocal values pertaining to this thread. This map is maintained * by the ThreadLocal class. */ ThreadLocal.ThreadLocalMap threadLocals = null; /* * InheritableThreadLocal values pertaining to this thread. This map is * maintained by the InheritableThreadLocal class. */ ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
    

    竟然Thread还也是有其它一个和threadLocals类型同样的变量,是还是不是很惊讶?竟然都并未有关切过。这inheritableThreadLocals是在何地被赋值的啊?大家来看看

    图片 2Paste_Image.png

    原先在new Thread()的时候,会将日前线程的inheritableThreadLocals传递给新创立线程的inheritableThreadLocals变量,即完结了壹回"华丽的正片"。

    1. 再来看看InheritableThreadLocal中的多少个方法
     protected T childValue(T parentValue) { return parentValue; } ThreadLocalMap getMap { return t.inheritableThreadLocals; } void createMap(Thread t, T firstValue) { t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue); }
    

    进而大家在子线程中调用get()方法的时候,会从子线程中的inheritableThreadLocals取值。而inheritableThreadLocals就是父线程在new Thread()的时候传递给子线程,一切都柳暗花明!!!难怪子线程能够收获到父线程设置的属性值。下边看四个粗略实例来证多美滋(Dumex)下:

    final InheritableThreadLocal<SpanId> inheritableThreadLocal = new InheritableThreadLocal<SpanId>(); inheritableThreadLocal.set(new SpanId("main thread")); System.out.println(inheritableThreadLocal.get; Runnable runnable = new Runnable() { @Override public void run() { System.out.println("-----------"); System.out.println("--->: " + inheritableThreadLocal.get;//父线程将属性值传递到子线程了 inheritableThreadLocal.set(new SpanId("inner thread")); System.out.println(inheritableThreadLocal.get; System.out.println(); } }; ExecutorService executorService = Executors.newFixedThreadPool;//手动修改线程池大小,这里设置为10,保证是新创建的线程,而不是直接取池中的线程。 executorService.submit; TimeUnit.SECONDS.sleep; System.out.println("after sleep-> " + inheritableThreadLocal.get; executorService.submit; //重新执行任务,又将main线程的inheritableThreadLocals属性值复制到子线程中。 TimeUnit.SECONDS.sleep; System.out.println("########"); SpanId span = inheritableThreadLocal.get(); System.out.println("main-> " + span.name);输出结果:main thread-------------->: main threadinner threadafter sleep-> main thread-------------->: main thread //这里依旧是main thread,因为是 new Thread(),所以将值传递进来了inner thread########main-> main thread
    

    将newFixedThreadPool中的线程数改成1再试一遍。实施结果如下:

    main thread-------------->: main threadinner threadafter sleep-> main thread-------------->: inner thread//由于线程数固定为1,所以第二次执行任务时直接取池中的线程,不会实现独立数据副本的拷贝,故不能传递父线程的数据。只能打印原来线程的数据。inner thread########main-> main thread
    

    3、AuthorName.java,用来存放books/book/author/name标签中的内容。

    监听器

    package com.ghgcn.event.service;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.context.ApplicationListener;import org.springframework.stereotype.Component;@Componentpublic class DemoEventListener implements ApplicationListener<DemoEvent> { private Logger logger = LoggerFactory.getLogger(DemoEventListener.class); @Override public void onApplicationEvent(DemoEvent event) { String msg=event.getMsg(); logger.debug("onApplicationEvent {}",event); logger.debug("onApplicationEvent {}",event); logger.debug("onApplicationEvent {}",event); logger.debug("onApplicationEvent {}",event); logger.debug("onApplicationEvent {}",event); logger.debug("onApplicationEvent {}",event); logger.debug("onApplicationEvent {}",event); logger.debug("onApplicationEvent {}",msg); System.out.println("DemoEventListener 接收到的消息 "+event); }}
    
    已知:

    doHandle()是贰个政工方法。

    2、Byname.java,用来存放在books/book/byname/name标签集合。

    事件

    Spring事件管理日常经过:

    • 定义Event类,继承org.springframework.context.ApplicationEvent。
    • 编写宣布事件类Publisher,达成org.springframework.context.ApplicationContextAware接口。
    • 蒙面格局setApplicationContext(ApplicationContext applicationContext)和发布办法publish(Object obj)。
    • 概念时间监听类EventListener,完毕ApplicationListener接口,达成方法onApplication伊芙nt(ApplicationEvent event)。
    三、ThreadLocal的弊端
    1. 跨线程的题材。由于ThreadLocal具有线程独立别本,线程之间互不压抑。所以它自然就管理不了跨线程的难点。未来考虑这么叁个急需,大家先看三个spring 服务代码示例:
     public Integer doHandle(){ Integer resultA = methodA(); Integer resultB = longTimeMethod();//耗时服务 Integer resultC = methodC(); Integer resultAll = mergeResult(resultA,resultB,resultC);//合并结果集 return resultAll; }
    

    7、Test1.java,生成映射XML文书档案到Java对象和测量检验

    实现 事件 ApplicationEvent

    smslog

    public class SmsLog implements Serializable { private static final long serialVersionUID = 1L; /** * id */ @TableId(value = "sms_log_id", type = IdType.AUTO) private Integer smsLogId; /** * 手机号 */ private String userPhone; /** * 短信内容 */ private String smsText; /** * 短信类型 0 注册 1 登陆 */ private int smsType; /** * 发送时间 */ private Date sendTime; /** * 发送状态 0 未发送 1发送成功 2发送失败 */ private Integer sendStatus; public SmsLog() { } public SmsLog(String userPhone, String smsText, int smsType) { this.userPhone = userPhone; this.smsText = smsText; this.smsType = smsType; } public SmsLog(String userPhone, String smsText, SmsTypeEnum smsType) { this.userPhone = userPhone; this.smsText = smsText; this.smsType = smsType.ordinal(); } public Integer getSmsLogId() { return smsLogId; } public void setSmsLogId(Integer smsLogId) { this.smsLogId = smsLogId; } public String getUserPhone() { return userPhone; } public void setUserPhone(String userPhone) { this.userPhone = userPhone; } public String getSmsText() { return smsText; } public void setSmsText(String smsText) { this.smsText = smsText; } public int getSmsType() { return smsType; } public void setSmsType(int smsType) { this.smsType = smsType; } public void setSmsTypeEnum(SmsTypeEnum smsType) { this.smsType = smsType.ordinal(); } public Date getSendTime() { return sendTime; } public void setSendTime(Date sendTime) { this.sendTime = sendTime; } public Integer getSendStatus() { return sendStatus; } public void setSendStatus(Integer sendStatus) { this.sendStatus = sendStatus; }}
    
    public class SendSmsEvent extends ApplicationEvent { private static final long serialVersionUID = 5819199428179496870L; private SmsLog smsSource; private boolean persistent=true;// 短信是否持久化 public SendSmsEvent(Object source) { super; } public SendSmsEvent(Object source, SmsLog sms) { super; this.smsSource = sms; } public static long getSerialversionuid() { return serialVersionUID; } public SmsLog getSmsSource() { return smsSource; } public boolean isPersistent() { return persistent; } /** * 设置短信是否持久化到库 * * @param persistent */ public void setPersistent(boolean persistent) { this.persistent = persistent; }}
    
    二、ThreadLocal的行使情形
    1. spring的业务传播本性将业务沿着当前线程进行传递.
    2. 稀有财富支配访谈例如数据库连接、分页等等都能够动用ThreadLocal来做。
    3. 遍及式追踪系统必要检查测量试验线程经过的有着链路的耗费时间情形。
    • 列出全数张开的互连网连接lsof -i

    • 列出富有展开的tcp互连网连接lsof -i tcp

    • 列出具备张开的udp网络连接lsof -i udp

    • 列出钦点的tcp端口境况lsof -i tcp:80

    • 列出钦点的udp端口景况lsof -i udp:55

    5、Book.java,用来存放books/book标签中的内容

    本文由澳门皇家娱乐场发布于澳门皇家娱乐场,转载请注明出处:spring事件传播,开拓技术员必会的Linux命令

    关键词:

上一篇:没有了

下一篇:没有了