分类: Java
2011-12-27 17:29:14
import java.util.Map;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
@SuppressWarnings("unchecked")
public class SqlMapClient {
public SqlMapClient(String s, String t) {
sqlMap = s;
type = t;
}
public SqlMapClient() {
}
private String type = null;
private String sqlMap = null;
// get、set方法 略
// 用于演示查询后返回一个String的返回结果
public String selectForObject(String sql, Map in) {
return this.toString();
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append("sqlMap", sqlMap)
.append("type", type).toString();
}
}
import java.util.Map;
@SuppressWarnings("unchecked")
public class MyService {
@DataSource(type="B", sqlMap="com/annotation/sql-map-config-B.xml")
private SqlMapClient sqlMapB = null;
@DataSource(type="A", sqlMap="com/annotation/sql-map-config-A.xml")
private SqlMapClient sqlMapA = null;
// get、set方法 略
// 模拟在DB-B数据库取得数据
public String selectForObjectFromB(String sql, Map in) {
return sqlMapB.selectForObject("", null);
}
// 模拟在DB-A数据库取得数据
public String selectForObjectFromA(String sql, Map in) {
return sqlMapA.selectForObject("", null);
}
}
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)
public @interface DataSource {
/**
* Dao的类型
* @return
*/
String type() default "A"; // 连接的数据库类型 A or B
String sqlMap() default ""; // Sql-Map-Config文件的路径,用于加载iBatis的SqlMapClient对象
}
IFieldWiring.java
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
public interface IFieldWiring {
Class extends Annotation> annotationClass();
void wiring(Object object, Field field);
}
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
public class DataSourceWiring implements IFieldWiring{
@Override
public void wiring(Object object, Field field) {
Object fieldObj = ReflectUtils.getFieldValue(object, field.getName()); // 获得field对应的对象
if (fieldObj != null) {
return;
}
DataSource annotation = field.getAnnotation(DataSource.class);
String type = annotation.type();
String sqlMap = annotation.sqlMap();
// 这里可以用缓存来实现,不用每次都去创建新的SqlMapClient对象
SqlMapClient sqlMapImpl = new SqlMapClient(sqlMap, type);
// 将生成SqlMapClient注入到bean对象的字段上
ReflectUtils.setFieldValue(object, field.getName(), SqlMapClient.class, sqlMapImpl);
}
@Override
public Class extends Annotation> annotationClass() {
return DataSource.class;
}
}
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.apache.commons.lang.StringUtils;
public class ReflectUtils {
/**
* 取得字段值
*
* @param obj
* @param fieldName
* @return
*/
public static Object getFieldValue(Object obj, String fieldName) {
if (obj == null || fieldName == null || "".equals(fieldName)) {
return null;
}
Class> clazz = obj.getClass();
try {
String methodname = "get" + StringUtils.capitalize(fieldName);
Method method = clazz.getDeclaredMethod(methodname);
method.setAccessible(true);
return method.invoke(obj);
} catch (Exception e) {
try {
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(obj);
} catch (Exception e1) {
e1.printStackTrace();
}
}
return null;
}
public static void setFieldValue(Object target, String fname, Class> fieldClass,
Object fieldObj) {
if (!fieldClass.isAssignableFrom(fieldObj.getClass())) {
return;
}
Class> clazz = target.getClass();
try {
Method method = clazz.getDeclaredMethod("set" + Character.toUpperCase(fname.charAt(0))
+ fname.substring(1), fieldClass);
method.setAccessible(true);
method.invoke(target, fieldObj);
} catch (Exception e) {
try {
Field field = clazz.getDeclaredField(fname);
field.setAccessible(true);
field.set(target, fieldObj);
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
}
import java.lang.reflect.Field;
public class MyAnnotationBeanProcessor {
/**
* 注入资源
* @param serviceObject
* @param fieldAutoWirings // 所有实现IFieldWiring的接口的对象,我们可以在此扩展
* @throws Exception
*/
public void wire(Object serviceObject, IFieldWiring
fieldAutoWirings)
throws Exception {
Class> cls = serviceObject.getClass();
for (Field field : cls.getDeclaredFields()) {
for (IFieldWiring fieldAutoWiring : fieldAutoWirings) {
if (field.isAnnotationPresent(fieldAutoWiring.annotationClass())) {
fieldAutoWiring.wiring(serviceObject, field);
break;
}
}
}
}
}
public class FieldWiringTest {
public static void main(String args[]) throws Exception {
MyAnnotationBeanProcessor processor = new MyAnnotationBeanProcessor();
MyService b = new MyService();
processor.wire(b, new DataSourceWiring()); // 注入DataSource资源
System.out.println(b.selectForObjectFromB("", null));
System.out.println(b.selectForObjectFromA("", null));
}
}
SqlMapClient[sqlMap=com/annotation/sql-map-config-B.xml,type=B]
SqlMapClient[sqlMap=com/annotation/sql-map-config-A.xml,type=A]
MyAnnotationBeanProcessor processor = new MyAnnotationBeanProcessor();
MyService b = new MyService();
processor.wire(b, new DataSourceWiring(), new InParamWiring()); // 注入DataSource、InParam资源