偶然看到一个Servlet的Filter实现,在doFilter方法中,发现有对Spring容器的访问,用法如下:
[code]
XxxService xxxService = SpringContextHolder.getApplicationContext().getBean("xxxService", XxxService.class);
[/code]
其中有个SpringContextHolder,看名称就能大概猜出来它的意思,里面保持一个Spring的Context,调用方式上看,是静态的。
实际代码也是这么实现的:
[code]
public class SpringContextHolder implements ApplicationContextAware {
private static ApplicationContext applicationContext;

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextHolder.applicationContext = applicationContext;
}

public static ApplicationContext getApplicationContext() {
return applicationContext;
}

public static Object getBean(String name) throws BeansException {
return applicationContext.getBean(name);
}
}
[/code]
整个的调用顺序是这样的:
[code]
1、服务启动,初始化SpringContextHolder,Spring的ApplicationContext注入到SpringContextHolder中。
2、有请求需要此Filter处理时,通过SpringContextHolder拿到Spring的容器,从中取出所需的bean。
[/code]

实际上用Spring还有一种更简单的做法,也是比较中规中矩的,不需要SpringContextHolder,使用原生的WebApplicationContext就可以从doFilter方法的request中取到:
[code]
ServletContext serveletContext = request.getSession().getServletContext();
WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(serveletContext);
XxxService xxxService = springContext.getBean("xxxService", XxxService.class);
[/code]
以上这种方式使用的前提是在web.xml配置了ContextLoaderListener
[code]
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
[/code]
如果没有配置这个ContextLoaderListener,只配置了DispatcherServlet,如下
[code]
<servlet>
<servlet-name>XXXX</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>XXXX</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
[/code]
使用默认的就不成了:WebApplicationContextUtils.getWebApplicationContext(serveletContext);
因为默认从servletContext中取的key是常量:WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
实际上只使用DispatcherServlet用的key是:FrameworkServlet.SERVLET_CONTEXT_PREFIX + getServletName();即org.springframework.web.servlet.FrameworkServlet.CONTEXT.XXXX
可使用以下方法获取,只是稍麻烦了一点。遍历取相应类型的实例
[code]
ServletContext servletContext = request.getSession().getServletContext();
WebApplicationContext springContext = null;
Enumeration<?> names = servletContext.getAttributeNames();
while (names.hasMoreElements()) {
String servletName = names.nextElement().toString();
Object obj = servletContext.getAttribute(servletName);
if (obj instanceof WebApplicationContext) {
springContext = (WebApplicationContext) obj;
System.out.println(servletName);
break;
}
}
if (webAppContext != null) {
XxxService xxxService = springContext.getBean("xxxService", XxxService.class);
}
[/code]

Java的常量在编译期会在引用处本地化,单个java文件改动后编译更新,容易由此引入问题。

举例说明:
本地为测试环境的测试代码,常量配置为测试域名test.xx.com
[code lang="java"]
public class A{
public static final String X_HOST = "test.xx.com";
}
[/code]
线上为正式域名:
[code lang="java"]
public class A{
public static final String X_HOST = "xx.com";
}
[/code]
调用代码为:
[code lang="java"]
public class B{
public static final String LURL = "http://" + A.X_HOST + "/";
public void xxx(){
...
String url = "http://" + A.X_HOST + "/";
...
}
}
[/code]
当需要修改B中省略的代码,只把B.java编译后的B.class替换到线上时,执行出错。
原因在开始时已经说明:在测试环境编译的时候,LURL和url中的A.X_HOST都被B类本地化了,B.class中只有值,没有引用信息。所以上线就错了。

Android出现丢包问题,备注一下:
问题:
Android在联通的GPRS网络下,偶现长期无法连接现象。

调查过程:
Android和服务端第一层,同时使用tcpdump抓包,碰到失败的情形后,分析两个包文件。
发现小报文传输没问题,大报文1516传输失败,服务器端无相应的包。SYN握手协商的MSS是1460,看起来正常。
初步怀疑联通网络不支持MSS1460的包,考虑X.25只支持536大小计划调整服务端MSS为536。
尔后发现大部分时候正常的报文也是1460,可以正常通讯。

- 阅读剩余部分 -

使用geohash搜索,当前位置越接近格的边缘,搜索结果越不准(格外的很近,却搜不到),无论怎么扩格大小或偏移,都无法解决此问题。
一种方法可解决此问题:搜索时,把当前格周边的8个格也取出来,一并搜索。

一个牛人提供了比较好用的工具:https://github.com/kungfoo/geohash-java

使用牛人的工具,只使用其GeoHash,代码如下:
private static final int GEO_CHAR_BITS = 5;

GeoHash bitPrecision = GeoHash.withBitPrecision(lat, lng, GEO_CHAR_BITS * 4);//根据当前位置取精度取geohash:当前格
GeoHash[] adjacent = bitPrecision.getAdjacent();//取当前格周边的8个格

这九个格拿到后,用GeoHash的toBase32()方法拿到字符串,匹配即可。

当社会越是公平的时候,越是细小的不公都会被争议;当社会层级森严时,最底层的人也能自得其乐,安于天命。
立法越全,越是有人钻漏洞,越要完善成更复杂的律法,就更有人去钻漏洞。

社会是一个复杂的组织形式,人也是一种复杂的生物。想起了老子的一句话:不尚贤,使民不争。

看到的一个观点:乡村里,对周边的人熟悉,道德约束力强;城市里,比较封闭,周边可能大部分都不认识,道德约束差。
结论:城市化进程加快后,大家的道德约束会越来越差。
想到的:这个道德更像是集体价值观,集体价值观也容易出现偏差。民风纯朴是困难的,各地几乎都会有歪风邪气。

恒星质量越大,内核受的压力就越大,聚变反应就更猛烈,温度也就越高。

越是大的恒星,寿命越短,死亡时的威力就更大,更壮烈。

附上质量与寿命的简单对照表:
恒星质量(以太阳为单位) 寿命
0.1 1000亿年
0.5 500亿
1 100亿
2 60亿
5 30亿
10 10亿
20 5亿
60 7000万年
100 400万年
120 270万年