存档

‘高级民工’ 分类的存档

位掩码

2013年1月3日 没有评论

位掩码的作用主要是想通过与或运算快速的判断是否选择了某个选项,常见的如在J2SE的弹窗中常用到给窗口加按钮,某个参数里有类似于BTN_OK|BTN_CANCEL|BTN_NO这样的代码,这个就是使用了位掩码。
位掩码的原理比较简单按8bit的一个例子。
0 0 0 0  0 0 0 1   –>1
0 0 0 0  0 0 1 0   –>2
0 0 0 0  0 1 0 0   –>4
0 0 0 0  1 0 0 0   –>8

位掩码总是2的n次方,如果上面的值分别对应a1,a2,a3,a4.
那么a1|a2 –>0 0 0 0  0 0 1 1
这个参数被传入方法中后一个判断可能是这样

if( state&(a1|a2) ==1)  {//state&a1
//当state为a1或a2时。。to do something
//假设state=1则,00000001&00000011=1

}

 

通过与运算如果是0则未设置,如果是1则设置

上面的代码如果不用位掩码可能的代码会是这样

if( state==a1||state==a2 ){

}

位掩码的好处是在一定程度上减少代码量,并可以使得一个变量可以表示多种状态,只需通过与运算即可知道是否带有某个状态。

分类: 高级民工 标签:

插件式开发OSGI

2013年1月2日 1 条评论

  元旦这几天一直在思考以前的一个想法,想做一个整合了Spring+hibernate+struts+quartz等常用框架的可实现模块化插件式加载的系统,如果是针对某一单一功能而不考虑通用性扩展的话做出一个满足自己需求的框架还是相对简单的。
  为了减少配置,倾向于更多的采用注解,主要是在Spring这块,目前已经实现的可以看之前的两篇关于Spring和Hibernate动态加载的文章,不过在后续的实践中发现这些方法并不是很好。首先在Spring动态加载获取Bean的时候如果需要手动去获取某个Bean那么会存在线程安全问题,因为需要改变Spring的当前ClassLoader这肯定是会导致冲突的。Hibernate这块由于其本身类加载器以及SessionFactory不能动态加入类映射关系,所以考虑为每一个需要用到hibernate的模块单独创建一个SessionFactory,不过有两个问题,第一为每个模块都创建SessionFactory感觉比较浪费资源用同一个呢又没有好的方法;第二,一个模块中的Dao操作是没有问题的,但是存在跨模块的调用时Dao的操作将出问题,体现在事务方面,因为不同模块的SessionFactory不一样,所以会导致Session也不一样。
  OSGI这个目前应该说还是比较潮的技术,而且基于OSGI开发的成功软件也比较多,Eclipse是一个典型,Andorid底层也用到了OSGI的一些标准,现在比较流行的OSGI框架有Eclipse的Equinox和Apache的Felix,这两个属于OSGI标准的实现,但要自己去整合Spring和hibernate基于这些框架似乎也不是那么容易,另外Spring有个SpringDM的玩意儿这个东西整合了Spring使用了一下感觉还行但不是很完善,主要是配置麻烦文档偏少,另外SpringDM被捐给Eclipse之后有个新的版本叫Gemini Blueprint的东西,主体还是SpringDM,下载其提供的Server后即Virgo这个基于Equinox的OSGI实现并且整合了Spring的容器后感觉这个就是我想要的东西。

  最近的业余目标就是改造Virgo满足我的要求整合Hibernate和Quartz.并尽量减少无用的配置。

分类: 生活, 高级民工 标签:

在动态加载的JAR中使用Spring

2012年12月28日 没有评论

  目的是在动态加载的JAR中使用Spring的功能,即动态把JAR中的Class加载到Spring中管理,目前设计为使用Annation来管理配置Spring,动态加入的代码如下:

//加载jar
JARClassLoader loader = new JARClassLoader();
loader.loadJar("c:/x3.jar");
 
//设置当前线程的classLoader
Thread.currentThread().setContextClassLoader(loader);
 
//注册bean
ApplicationContext context = SystemCore.getApplicationContext();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner((DefaultListableBeanFactory)
context.getAutowireCapableBeanFactory());//使用Spring的注解自动扫描
//扫描jar中的包路径,使用通配符,另外在导出jar时必须选择add directory entries(即把目录也加入到jar中)
//否则spring扫描时将无法找到class
scanner.scan("com.test.moduleA.*");
 
//手动拿jar包里的bean的实例时因为存在ClassLoader的隔离虽然在开始设置了ContextClassLoader
//但是Spring默认getBean的时候并没有每次都去拿最新的ContextClassLoader使用,所以需要手动设置Bean的ClassLoader
//因为是手动设置的这里存在线程安全的问题...不知道有没有其他方法.
DefaultListableBeanFactory factory = (DefaultListableBeanFactory)context.getAutowireCapableBeanFactory();
		factory.setBeanClassLoader(loader);
 
System.out.println(context.getBean("questionDaoImpl"));
分类: 高级民工 标签: ,

Hibernate动态加载时class的加入

2012年12月27日 没有评论

  最近在搞一个模块化的功能,自己写着玩的,最终目的是整合osgi,Hibernate,Spring,Struts等常用框架,并能在模块中动态加入到这些框架中。今天遇到一个Hibernate动态加入时找不到实体类的问题,翻看源码在ReflectHelper中找到答案:

	public static Class classForName(String name) throws ClassNotFoundException {
		try {
			ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
			if ( contextClassLoader != null ) {
				return contextClassLoader.loadClass(name);
			}
		}
		catch ( Throwable t ) {
		}
		return Class.forName( name );
	}

在加载类时是通过在当前线程的classLoader中查找类(ClassLoader有隔离机制),所以在动态加载ClassLoader之前需要把当前线程的contextClassLoader设置为我们自己定义的ClassLoader.代码如下:

	Thread.currentThread().setContextClassLoader(loader);//设置当前线程的ContextClassLoader
	ModuleSupporter.hibernateMapping(new File("c:/x3.jar"));

后记:
由于Hibernate本身用了大量反射并且对多个ClassLoade的情况考虑不是很充分,另外动态加入只是加入到Configuration所以需要要单独创建SessionFactory,感觉会浪费资源还有就是多个模块的时候SessionFactory的不同必然会有事务不好控制的问题。

分类: 高级民工 标签: ,

BlazsDS中在MessageInterceptor里获取Flex层方法的注解

2012年10月17日 没有评论

  项目上的一蛋疼的需求,解决方案是需要在flex层进行一次拦截获取到方法上自定义的Annotation的信息来实现这个需求。下面是我分析BlazeDS后得到的获取flex层Method的Annotation的代码。

public class FlexMessageInterceptor implements MessageInterceptor {
 
 
	@Override
	public Message postProcess(MessageProcessingContext arg0, Message arg1,
			Message arg2) {
		return arg2;
	}
 
	@Override
	public Message preProcess(MessageProcessingContext arg0, Message arg1) {
 
 
		if(arg1 instanceof RemotingMessage){
			//记录日志的相关操作
			RemotingMessage remotingMessage = (RemotingMessage)arg1;
			//如果方法名为空则不记录日志,可能是flex自己的client ping等操作
			if(!StringUtil.isBlank(remotingMessage.getOperation())){
				MessageBroker messageBroker = MessageBroker.getMessageBroker("_messageBroker");
				RemotingDestination destination = (RemotingDestination)messageBroker.getService("remoting-service").getDestinations().get(arg1.getDestination());
 
				MethodMatcher methodMatcher = destination.getMethodMatcher();
				FactoryInstance factoryInstance = destination.getFactoryInstance();
				Object instance = factoryInstance.lookup();
				//这个method是cglib代理了的,不知道是不是我用spring整合了BlazsDS的原因
				Method method = methodMatcher.getMethod(instance.getClass(), remotingMessage.getOperation(), remotingMessage.getParameters());
 
				//所以需要用spring提供的一个工具来获取方法的注解
				ModuleLog moduleLog = AnnotationUtils.findAnnotation(method,ModuleLog.class);
 
				//记录日志
				if(moduleLog!=null){
					//做该做的事情
				}
			}
		}
 
		return arg1;
	}
 
}

其余不做过多解释,debug两下基本就可以拿到自己想要的东西。如果疑问留言。

分类: 源码分享, 高级民工 标签: