出售shadowsocks代理帐号,分摊vps费用【长期有效】

Spring源码分析(一)——DelegatingFilterProxy

在开发web项目时,经常需要添加自己的filter,在web.xml文件中一般都这么定义自己的filter,filter的name是自己定义的beanName,class一般都是使用org.springframework.web.filter.DelegatingFilterProxy。 配置如下:

<filter>
    <filter-name>userInfoFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>userInfoFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

DelegatingFilterProxy 是Spring的一个类,它实现了GenericFilterBean,而GenericFilterBean又实现了javax.servlet.Filter接口,并对Filter的init方法进行了重写,而Filter的doFilter交给其子类去实现。而GenericFilterBean的init方法内部调用了GenericFilterBean的initFilterBean方法。该方法的默认实现为空,其采用了模板方法的设计模式交给其子类去实现initFilterBean的具体逻辑。

public final void init(FilterConfig filterConfig) throws ServletException {
    //...此处省略部分代码
    // Let subclasses do whatever initialization they like
    initFilterBean();
    //...此处省略部分代码
}

现在,来看看DelegatingFilterProxy的initFilterBean的现实代码

@Override
protected void initFilterBean() throws ServletException {
    synchronized (this.delegateMonitor) {
        if (this.delegate == null) {
            // If no target bean name specified, use filter name.
            if (this.targetBeanName == null) {
                this.targetBeanName = getFilterName();
            }
            // Fetch Spring root application context and initialize the delegate early,
            // if possible. If the root application context will be started after this
            // filter proxy, we'll have to resort to lazy initialization.
            WebApplicationContext wac = findWebApplicationContext();
            if (wac != null) {
                this.delegate = initDelegate(wac);
            }
        }
    }
}

该方法中有两处关键的地方this.targetBeanName = getFilterName()与WebApplicationContext wac = findWebApplicationContext()。前者得到web.xml中filter对应的名字,将其赋予为targetBeanName;后者 得到一个WebApplicationContex对象,这个接口大家应该很熟悉其续承了ApplicationContext,而通过其getBean方法我们便可以得到在application-context.xml配置文件中配置的bean。 先来看看 initDelegate对应的代码:

protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
    Filter delegate = wac.getBean(getTargetBeanName(), Filter.class);
    if (isTargetFilterLifecycle()) {
        delegate.init(getFilterConfig());
    }
    return delegate;
}

Filter delegate = wac.getBean(getTargetBeanName(), Filter.class),便是利用我们在web.xml配置文件设置的<filter-name>userInfoFilter</filter-name>去application-context.xml配置文件中找到具体的实现类。 所以,在application-context.xml文件中bean对应的id一定要与web.xml中的filter-name一致。

Java设计模式教程(二)——责任链模式(Chain of Responsibility)

责任链模式(Chain of Responsibility)是行为模式之一,该模式构造一系列分别担当不同职责的类的对象来共同完成一个任务,这些类的对象之间像链条一样紧密相连,所以被称作责任链模式。

一、应用场景:

例1:比如客户要完成一个任务,这个任务包括a,b,c,d四个部分。 首先客户Client把任务交给A,A完成a部分之后,把任务交给B,B完成b部分,…,直到D完成d部分。
例2:web开发中的filter和interceptor

二、UML类图
责任链模式

抽象处理者(Handler)角色:定义一个请求的接口。如果需要可以定义个一个方法用来设定和返回下家对象的引用。
具体处理者(ConcreteHandler)角色:如果可以处理就处理请求,如果不能处理,就把请求传给下家,让下家处理。也就是说它处理自己能处理的请求且可以访问它的下家。 阅读详细 »

老员工的工资为什么会倒挂?

因为你的薪酬待遇只有在入职的那一刻才是被人力部门以市场价值评估。

之后的若干年加薪都是遵循企业内部晋升通道,如果企业加薪幅度赶不上同岗位市场薪酬回报的上涨幅度,就会出现工资倒挂。

在2012年,某岗位本科应届毕业生起薪2K—3K;

但到了2015年,同岗位的本科应届毕业生起薪已经涨到了5K(如果低于5K面试通知都发不出去);

如果2012年入职的毕业生小A合同起薪是2K,小A在工作中尽职尽责,每年都能拿到30%的调薪(部门上限了,少数);

那么3年后,小A的薪酬是4394/月(2000*1.3*1.3*1.3),他已具备三年工作经验;同时,新入职的员工小B是应届毕业生,起薪5K。

小A不想走,部门领导也舍不得放,但部门领导能争取到的调薪上限已经是30%;

小A跳槽的话作为3年熟练员工起薪8K,有管理经验还可以再上浮,这些信息对各方都是公开的,不存在信息不对称;

但是,部门领导想将小A的薪酬从5K提升到8K将会面对千山万水甚至要高层特批,而外面招一个与小A同资历甚至不如小A的人,只要提一个招聘需求就好;

最终,小A还是走了,虽然部门领导极力挽留,但30%是越不过的坎儿; 阅读详细 »

如何准确听出英语中的数字

无论是在各类考试的英语听力中,还是练习口语对话,数字往往是关键信息,然而大多人对这都是稀里糊涂。年月日的正确读法?序数词怎么读?分数、小数怎么读?……这些英语中的数字表达你都会读吗??

先看两个例子:

1,345,233 = one million, three hundred and forty-five thousand, two hundred and thirty-three.

1,684,234,465 = one billion, six hundred and eighty-four million, two hundred and thirty-four thousand, four hundred and sixty-five.

仔细看看,有没有发现规则?

英语里把一个基数词的基础上进一位用ten表示,进两位用one hundred,进三位时就用一个新的基数词来代替,然后在新词的基础上进位用相同的方法!

好吧,我再讲一个实用的规则,这次是关于“teen”和“ty”的区别,15、50听起来傻傻分不清楚!

“-teen”和“-ty”是比较容易混淆的一对读音。我们可以通过音和音素的差异来区别两者。含有“-teen ”的词有两个重音,即“-teen”要重读,且“-teen”中的元音为长元音[ti:n],发音长而清晰;而含有 “-ty”的词只有一个重音,即“-ty”不重读,且“-ty”中的元音为短元音[ti],发音短而急促。 阅读详细 »

Java工程师应该读的几本书

《深入理解Java虚拟机:JVM高级特性与最佳实践》

深入理解Java虚拟机:JVM高级特性与最佳实践

《Java并发编程实战》

Java并发编程实战 阅读详细 »

防砸玻璃

工作人员演示防砸玻璃, [吃惊]卧槽!!最后一下太惊险了, [可怜]幸好戴着面罩!
 防砸玻璃

你应该知道的 RPC 原理

现在互联网公司的系统都由成千上万大大小小的服务组成,各服务部署在不同的机器上,由不同的团队负责。这时就会遇到两个问题:1)要搭建一个新服务,免不了需要依赖他人的服务,而现在他人的服务都在远端,怎么调用?2)其它团队要使用我们的服务,我们的服务该怎么发布以便他人调用?下文我们将对这两个问题展开探讨。

[java]
public interface HelloWorldService {
String sayHello(String msg);
}

public class HelloWorldServiceImpl implements HelloWorldService {
@Override
public String sayHello(String msg) {
String result = "hello world " + msg;
System.out.println(result);
return result;
}
}

public class Test {
public static void main(String[] args) {
HelloWorldService helloWorldService = new HelloWorldServiceImpl();
helloWorldService.sayHello("test");
}
}
[/java]

1 如何调用他人的远程服务

由于各服务部署在不同机器,服务间的调用免不了网络通信过程,服务消费方每调用一个服务都要写一坨网络通信相关的代码,不仅复杂而且极易出错。

如果有一种方式能让我们像调用本地服务一样调用远程服务,而让调用者对网络通信这些细节透明,那么将大大提高生产力,比如服务消费方在执行helloWorldService.sayHello(“test”)时,实质上调用的是远端的服务。这种方式其实就是RPC(Remote Procedure Call Protocol),在各大互联网公司中被广泛使用,如阿里巴巴的hsf、dubbo(开源)、Facebook的thrift(开源)、Google grpc(开源)、Twitter的finagle等。

要让网络通信细节对使用者透明,我们自然需要对通信细节进行封装,我们先看下一个RPC调用的流程:
RPC调用流程

阅读详细 »

立体迷宫

有创意、很好玩:用一个长度为1格的梯子,从左下那里爬到最顶端的旗子处
迷宫

如何成为卓有成效的管理者?

“管理学之父”彼得·德鲁克写的《卓有成效的管理者》很好的解答了这个问题,告诉了我们:一群平凡人,能做出不平凡的事业吗?这是完全可以做到的。只要我们组织中的每一个人都能做到卓有成效。卓有成效可以学会吗?卓有成效是可以学会的。每个人都必须卓有成效吗?卓有成效是管理者必须做到的事。
卓有成效的管理者 阅读详细 »

如何避免故障?

对每一个程序员而言,故障都是悬在头上的达摩克利斯之剑,都唯恐避之不及,如何避免故障是每一个程序员都在苦苦追寻希望解决的问题。对于这一问题,大家都可以从需求分析、架构设计 、代码编写、测试、code review、上线、线上服务运维等各个视角给出自己的答案。

我们大部分服务都是如下的结构,既要给使用方使用,又依赖于他人提供的第三方服务,中间又穿插了各种业务、算法、数据等逻辑,这里面每一块都可能是故障的来源。如何避免故障?我用一句话概括,“怀疑第三方,防备使用方,做好自己”。

故障

怀疑第三方

坚持一条信念:“所有第三方服务都不可靠”,不管第三方什么天花乱坠的承诺。基于这样的信念,我们需要有以下行动。

有兜底,业务降级

如果第三方服务挂掉怎么办?我们业务也跟着挂掉?显然这不是我们希望看到的结果,如果能制定好降级方案,那将大大提高服务的可靠性。举几个例子以便大家更好的理解。

比如我们做个性化推荐服务时,需要从用户中心获取用户的个性化数据,以便代入到模型里进行打分排序,但如果用户中心服务挂掉,我们获取不到数据了,那么就不推荐了?显然不行,我们可以在cache里放置一份热门商品以便兜底;

阅读详细 »