Java

RabbitMQ 入门 ( with camel )

Submitted by Lizhe on Wed, 06/21/2017 - 15:53

rpm -Uvh http://download.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-9.noarch.rpm

yum install erlang

wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.10/rabbitmq-server-3.6.10-1.el7.noarch.rpm

 

yum install rabbitmq-server-3.6.10-1.el7.noarch.rpm

 

因为是在docker容器下, 没有systemctl, 所以我尝试使用/usr/lib/rabbitmq/bin/rabbitmq-server 直接启动rabbitmq

SpringBatch

Submitted by Lizhe on Tue, 06/20/2017 - 13:55

2013年我在花旗工作的时候最早接触的批处理平台是Autosys, 在那之前我并有太多的批处理程序经验

我们在autosys上维护大量的Perl语言和Java语言脚本, autosys提供了一系列的查询, 调用, 容错机制 在那之后我就被它深深吸引住了

在那之后我开始尝试寻找autosys的开源代替品, 正是在那个时候我接触了springbatch

springbatch虽然没有提供像autosys那样的Web界面, job之间的依赖关系, 分组等功能, 但是基于spring平台强大的共用库, 它可以很方便的继承spring executor, ioc容器, 数据库工具, 同时springbatch提供了数据库支持, 所以你可以很方便的控制job的运行状态和信息的持久化

写一个web界面并不是很难的事

起初我使用springbatch是集成在B/S系统的springmvc之上的, 后来在infonova平台上做数据迁移, 既存系统上的模型是springboot+springbatch , 稍微调查了一下发现自从springboot推出之后, springbatch的官方helloworld竟然也变成了使用springboot

springmvc cxf webservice 入门(2)

Submitted by Lizhe on Mon, 06/12/2017 - 23:03

在这个例子中, 我要把上一个例子中 "代码优先" 的方式替换成 "契约优先" , 其他都一样

之前我们说过 "契约优先" 的方式需要开发人员先定义 wsdl 契约, 这里我图个省事, 把之前代码优先方式生成的wsdl直接拿来用了 ( 坏笑 )

完整的内容可以到 https://github.com/zl86790/download/blob/master/wsdlfirstws.zip 下载

wsdl 文件内容为

springmvc cxf webservice 入门(1)

Submitted by Lizhe on Mon, 06/12/2017 - 15:46

例子代码在 https://github.com/zl86790/download/blob/master/springws_code_first.zip

这几天改一个soap协议的webservice, 发现已经有差不多4年没再写过soap应用了, 花了点时间重新总结一下

首先需要说明的是 soap协议是一种"应用协议" , 它只是约束了传输数据的一种格式 而 大名鼎鼎的 http协议 是一种 "网络传输协议" , soap协议的数据包实际上可以理解成是"搭载"在http协议上发送的

要构建基于soap的应用, 你首先需要一个wsdl契约,

wsdl包含xsd和operation 两个部分, 其中xsd用来定义数据格式, 比如一个普通的java bean都有哪些字段, 而operation用来定义行为, 描述服务都提供了哪些方法

一个普通的java bean可能类似以下形式

如何通过反射调用(黑进)私有方法

Submitted by Lizhe on Thu, 06/08/2017 - 18:32

私有方法的api不一定就是完全安全的, 单例模式的私有构造器也不一定能保证自己一定是单例

在产品平台上做开发, 有时候你总会需要jad, 继承, cglib 或者 反射

package name.lizhe;

public class Employee {
    
    private void setSalary(int i){
        System.out.println("changed salary to:"+i);
    }
    
}
 

 

 

package name.lizhe;

tomcat classloader 加载class顺序

Submitted by Lizhe on Tue, 06/06/2017 - 16:11

今天下午被同事问到如果我有两个不同版本的class分别放在两个module里如何处理(我们项目里的module是分布在不同的war包里的)

然后引出下面的问题

1. 完全相同(同包同名)的class如何加载

2. 完全相同的class如果在不同war包里如何加载

印象中应该是不同war包各自加载自己的, 猜测是因为会启动各自的application级别classloader, 稍微调查之后发现自己原来的认识不够深入

参考 http://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html

我们知道jvm加载class默认是采用 父类委托 模型, 这个模型在之前的文章中我提到过

参考 http://lizhe.name.csdn.net/node/91

 

java默认提供3种classloader

1. Bootstrp loader 

加载%JAVA_HOME%/jre/lib,-Xbootclasspath参数指定的路径以及%JAVA_HOME%/jre/classes中的类

2. ExtClassLoader  

java 自定义 annotation

Submitted by Lizhe on Sat, 05/27/2017 - 16:56

 

 

package myanno;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAutoValue {
    public String value() default "";
}

sso 单点登录

Submitted by Lizhe on Sat, 05/27/2017 - 15:50

其实没什么神秘的, 如果使用cookie的话不能跨域

a.lizhe.name 和 b.lizhe.name 两个子域名可以共享lizhe.name的cookie 所以有些限制

使用memcached代替cookie就可以了

参考下面的时序图

sso

 

代码太多了直接写了个简单项目放在github了

https://github.com/zl86790/SimpleSSO

 

首先sso的登录画面

如何正确停止线程

Submitted by Lizhe on Wed, 05/24/2017 - 00:18

这个话题完全是由于 http://lizhe.name.csdn.net/node/102 带出来的

在谈论这个话题之前,首先我要申明一个概念, java本身不推荐你杀死任何线程而是推荐你要"让它自己运行完毕",然后我们来看下面几个概念

1. stop是不安全的, stop会释放持有的全部锁然后直接杀死线程,可能会造成数据不一致,而且已经过期,会立即杀死线程

2. interruput 不会立即杀死线程

    当线程处于运行状态时,interrupt不会终止线程,只是设置了一个表示位

    当线程处于阻塞状态(如调用sleep、wait、join等地方) 会抛出一个异常InterruptedException,并且中断状态也将被清除,这样线程就得以退出阻塞的状态

3. ExecutorService shutdown方法会让线程池停止接受新任务,但是不会终止或暂停任何当前持有的任务