用代理给Model增加getter和setter方法行不行?

V小刚 发布于 2014/03/29 15:51
阅读 344
收藏 0

@JFinal 你好,想跟你请教个问题:

    我的项目组中很多人喜欢用带getter和setter方法的model,使用jfinal后突然没了getter、setter,他们感觉 非常的不习惯,我总是劝他们改变一下习惯,但是你也知道习惯这个东西一旦养成是很难改变的,为了照顾他们我不得不在model中增加getter setter并添加一些代码来结合jfinal的Model,小项目中几个十来个model这样做是没有任何问题的,但是随着项目的变大,model越来越多,再这样做就太难受了,于是我想用代理model来解决这个问题。

这是我的源代码(这是测试,并不通用):

项目中的类

App.java

package test;

import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.druid.DruidPlugin;

public class App {
	static DruidPlugin dp;
	static ActiveRecordPlugin arp;

	public static void main(String[] args) {
		startPlugins();
		// 生成一个代理对象,替代用new创建
		User user = ModelManager.getModel(User.class);
		user.setName("张三");
		// 这里应该输出"张三"
		System.out.println(user.getStr("name"));
		user.save();

		stopPlugins();
	}

	private static void startPlugins() {
		dp = new DruidPlugin("jdbc:mysql://localhost:3306/test", "root", "root");
		dp.start();
		arp = new ActiveRecordPlugin(dp);
		arp.addMapping("user", User.class);
		arp.setShowSql(true);
		arp.start();

	}

	private static void stopPlugins() {
		arp.stop();
		dp.stop();
	}
}



GetterSetterInterceptor.java

package test;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class GetterSetterInterceptor implements MethodInterceptor {

	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		// 从setName方法中获取属性名 name
		String methodName = method.getName();
		String attrName = methodName.substring(3, methodName.length());
		attrName = attrName.replaceFirst(attrName.substring(0, 1), attrName
				.substring(0, 1).toLowerCase());
		// 调用代理对象的set(attr, value)方法
		Method setMethod = obj.getClass().getMethod("set", String.class,
				Object.class);
		setMethod.setAccessible(true);
		setMethod.invoke(obj, attrName, args[0]);
		return proxy.invokeSuper(obj, args);
	}

}



ModelManager.java

package test;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.CallbackFilter;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.NoOp;

public class ModelManager {
	/**
	 *通过这个方法创建Model代理对象,替代用new创建
	 * @param classData
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T>  T getModel(Class<T> classData){
		Enhancer en=new Enhancer();
		en.setSuperclass(classData);
		en.setCallbackFilter(new CallbackFilter() {
			public int accept(Method method) {
				if(!method.getName().equals("setName"))return 1;
				return 0;
			}
		});
		en.setCallbacks(new Callback[]{new GetterSetterInterceptor(),NoOp.INSTANCE});
		return (T)en.create();
	}


}



User.java

package test;

import com.jfinal.plugin.activerecord.Model;

/**
 * 
 */
public class User extends Model<User> {

	public static final User dao = new User();

	private static final long serialVersionUID = 1L;

	private int id;

	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

}



程序运行后就出现这个错误

因为我接触java不久,平时也很少使用代理,但是你写框架应该会经常使用代理所以我想请教一下问题出在哪儿?能否用代理的方式给jfinal的model增加getter和setter方法?如果可以的话,用户又可以少写好多代码了

加载中
0
JFinal
JFinal


不用这么麻烦吧,这样写就打完收工:

public class User extends Model<User> {
  public static final User dao = new User();
  
  public void setName(String name) {
    set("name", name);
  }

  public String getName() {
    return getStr("name");
  }

  // 其它 getter setter ......
}

   话说你们项目组的朋友们以前被 getter setter 虐习惯了,不受虐一下子还不习惯 

V小刚
V小刚
回复 @JFinal : 今天去了一下jfinal.com 恭喜恭喜啊 !建议在jfinal.com中增加一个插件模块哦 方便用户查询 如果更多人来写插件那jfinal的生命力就更强了!
JFinal
JFinal
回复 @V小刚 : just do it
V小刚
V小刚
回复 @JFinal : 这个想法还真有过
V小刚
V小刚
有的Model属性二三十个 每个属性的getter和setter都去添点代码 这样就有点痛苦了.....
JFinal
JFinal
回复 @V小刚 : 那你还不如写个程序自动生成代码,专门针对于Model 生成 getter setter, AccessMethodBuilder.build(String modelFileName)
下一页
返回顶部
顶部