做j2ee的朋友,我都听说过aop,ioc等概念。其实他们都可以称为j2ee的一种设计模式。
其中核心的技术使用java语言中的reflect(反射)机制。用过spring的人都会想怎么实现这中ioc容器,进行管理bean呢?先了解一下反射。
java发射机制,实际是给应用提供一个自审的机制。可以通过应用来获得运行起对象的各种属性和行为。这很重要,正是因为有了这个,才可以动态的注入运行期动态对象的属性数据。下面是我在实现一个一个java对象的一个包装。主要用来解决属性的检查和数据的获取,以简化其访问的方式。
/*
* Created on 2005-9-19
*
* http://www.soosoo.com.cn
* Copyright (C) 2005 Version
*/
package com.paic.paonline.award.util;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Category;
/**
* @author ex_wangjianhua
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class BeanRefecter {
private Category log=Category.getInstance(this.getClass());
public List getNotNullFields(Object param){
Class cs=param.getClass();
Field[] f=cs.getDeclaredFields();
List list=new ArrayList();
try {
for(int i=0;i Field fd=f[i];
Object obj=this.invokeGetMethod(fd,param);
if(obj!=null){
list.add(fd);
}
}
return list;
} catch (IllegalArgumentException e) {
log.error("error get fields arr for msg"+e.getMessage());
return null;
}
}
public String getNotNullFieldsStr(Object param){
Class cs=param.getClass();
Field[] f=cs.getDeclaredFields();
StringBuffer buf=new StringBuffer();
try {
for(int i=0;i Field fd=f[i];
Object obj=this.invokeGetMethod(fd,param);
if(obj!=null){
buf.append(fd.getName()+",");
}
}
if(buf.length()>0)
buf.deleteCharAt(buf.length()-1);
return buf.toString();
} catch (IllegalArgumentException e) {
log.error("error get fields str for msg"+e.getMessage());
return null;
}
}
public String getNotNullParamStr(Object param){
Class cs=param.getClass();
Field[] f=cs.getDeclaredFields();
StringBuffer buf=new StringBuffer();
try {
for(int i=0;i Field fd=f[i];
Object obj=this.invokeGetMethod(fd,param);
if(obj!=null){
buf.append("?"+",");
}
}
if(buf.length()>0)
buf.deleteCharAt(buf.length()-1);
return buf.toString();
} catch (IllegalArgumentException e) {
log.error("error get param str for msg"+e.getMessage());
return null;
}
}
public Object getFieldValue(Field f,Object bean){
try {
return f.get(bean);
} catch (IllegalArgumentException e) {
return null;
} catch (IllegalAccessException e) {
return null;
}
}
public Object invokeGetMethod(Field f,Object param){
String fName=f.getName();
StringBuffer buf=new StringBuffer();
buf.append("get");
buf.append(fName.substring(0,1).toUpperCase());
buf.append(fName.substring(1));
String mName=buf.toString();
try {
Method method=param.getClass().getDeclaredMethod(mName,null);
return method.invoke(param,null);
} catch (SecurityException e) {
return null;
} catch (NoSuchMethodException e) {
return null;
} catch (IllegalArgumentException e) {
return null;
} catch (IllegalAccessException e) {
return null;
} catch (InvocationTargetException e) {
return null;
}
}
//call bean set method
public void invokeSetMethod(Field f,Object param,Object value) throws Exception{
String fName=f.getName();
StringBuffer buf=new StringBuffer();
buf.append("set");
buf.append(fName.substring(0,1).toUpperCase());
buf.append(fName.substring(1));
String mName=buf.toString();
Class [] pm=new Class [1];
pm[0]=f.getType();
Object[] in=new Object[1];
in[0]=value;
Method method=param.getClass().getDeclaredMethod(mName,pm);
method.invoke(param,in);
}
public void invokeSetMethod(String fName,Object param,Object value) throws Exception{
StringBuffer buf=new StringBuffer();
buf.append("set");
buf.append(fName.substring(0,1).toUpperCase());
buf.append(fName.substring(1));
String mName=buf.toString();
Field f=param.getClass().getDeclaredField(fName);
Class [] pm=new Class [1];
pm[0]=f.getType();
Object[] in=new Object[1];
in[0]=value;
Method method=param.getClass().getDeclaredMethod(mName,pm);
method.invoke(param,in);
}
}
有了这个类。就可以动态的获取任何javaBean对象的数据,而不用知道他的具体定义.大家可以想象一下
想ibatis这种sql mapping的工具,对java对象到数据表的映射实现了.通过xml文件可以获得bean的属性到字段的定义。通过属性就可以完成java对象到数据库记录的相互转化。