关于使用cglib动态代理的问题

tianpeng91 发布于 2012/06/30 22:14
阅读 4K+
收藏 0

我想自己做一套ORM的产品,然后在做某一部分时,因为所有方法都需要调用一个公共方法,因此想使用动态代理,后来选择了CGLib。但在代理时出现了这样一个问题。

net.sf.cglib.core.CodeGenerationException: java.lang.NoSuchMethodException-->org.zhc.jdbc.BaseDAO$$EnhancerByCGLIB$$724bfabe.<init>(com.mysql.jdbc.JDBC4Connection)
	at net.sf.cglib.core.ReflectUtils.getConstructor(ReflectUtils.java:248)
	at net.sf.cglib.core.ReflectUtils.newInstance(ReflectUtils.java:220)
	at net.sf.cglib.proxy.Enhancer.createUsingReflection(Enhancer.java:639)
	at net.sf.cglib.proxy.Enhancer.firstInstance(Enhancer.java:538)
	at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:225)
	at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
	at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:304)
	at org.zhc.jdbc.BaseDAOProxy.getProxy(BaseDAOProxy.java:18)
	at org.zhc.jdbc.EntityManager.persist(EntityManager.java:84)
	at TestMYORM.main(TestMYORM.java:55)
Caused by: java.lang.NoSuchMethodException: org.zhc.jdbc.BaseDAO$$EnhancerByCGLIB$$724bfabe.<init>(com.mysql.jdbc.JDBC4Connection)
	at java.lang.Class.getConstructor0(Class.java:2721)
	at java.lang.Class.getDeclaredConstructor(Class.java:2002)
	at net.sf.cglib.core.ReflectUtils.getConstructor(ReflectUtils.java:244)
	... 9 more

我的几个类是这样的。。。

BaseDAO:

只有一个构造有参构造方法

public BaseDAO(Connection connection) {
		this.connection = connection;
	}

然后代理类是这样写的:

package org.zhc.jdbc;

import java.lang.reflect.Method;
import java.sql.Connection;

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

public class BaseDAOProxy implements MethodInterceptor {

	private Enhancer enhancer = new Enhancer();

	@SuppressWarnings("unchecked")
	public <T> T getProxy(Class<T> clazz, Connection connection) {
		enhancer.setCallback(this);
		//enhancer.setSuperclass(clazz);
		return (T) enhancer.create(new Class[] { connection.getClass() },
				new Object[] { connection });
		//return (T) enhancer.create();
	}

	@Override
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		System.out.println("begin......" + obj.getClass().getName() + "."
				+ method.getName());
		// 通过代理类调用父类中的方法
		Object result = proxy.invokeSuper(obj, args);
		System.out.println("end......");
		return result;
	}

}

然后就出现以上的错误了,麻烦各位大侠帮我解决下,这是为什么呢?为什么不能动态代理有参数的构造方法呢?

加载中
0
JackyYong
JackyYong
能否将完整的代码发过来, 谢谢! 可以联系我Q:133358551
tianpeng91
tianpeng91
由于代码较多,我在上面贴了相关代码,麻烦解答下,谢谢!
0
tianpeng91
tianpeng91

额 ,,,完整代码可能有点多,而且,因为小弟只有一年的开发经验,目前有点乱,我就把相当的代码贴上来吧。

这个是EntityManager.java中的一个方法,会调用BaseDAOProxy.java

/**
	 * 持久化Entity
	 * 
	 * @param entity
	 *            实体类的对象
	 * @return 
	 */
	public boolean persist(Object entity) {
		boolean persist = false;
		try {
			if (connection.isReadOnly()) {
				log.error("Read-only database, can not perform the insert operation");
				throw new UpdateException(
						"Read-only database, can not perform the insert operation");
			} else {
				BaseDAOProxy proxy = new BaseDAOProxy();
				BaseDAO baseDAO = proxy.getProxy(BaseDAO.class, connection);
				// BaseDAO baseDAO = new BaseDAO(connection);
				persist = baseDAO.save(entity);
			}
		} catch (SQLException | UpdateException e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
		return persist;
	}

下面是BaseDAOProxy.java的完整代码,目前只是测试代理是否成功,因此没有完整逻辑:

package org.zhc.jdbc;

import java.lang.reflect.Method;
import java.sql.Connection;

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

public class BaseDAOProxy implements MethodInterceptor {

	private Enhancer enhancer = new Enhancer();

	@SuppressWarnings("unchecked")
	public <T> T getProxy(Class<T> clazz, Connection connection) {
		enhancer.setCallback(this);
		return (T) enhancer.create(new Class[] { connection.getClass() },
				new Object[] { connection });
	}

	@Override
	public Object intercept(Object arg0, Method arg1, Object[] arg2,
			MethodProxy arg3) throws Throwable {
		System.out.println("---------proxy");
		return null;
	}

}

最后贴上BaseDAO.java的部分相关代码:

private Connection connection;
	private final Logger log = LoggerFactory.getLogger(EntityManager.class);

	public BaseDAO(Connection connection) {
		this.connection = connection;
	}

我的问题是如何使用CGLib来实现带参的构造函数动态代理,谢谢了!!!

0
邸星星
邸星星

 

(T) enhancer.create(new Class[] { connection.getClass() }, 
                 new Object[] { connection });  

改成 下面这样试试。(因为 connection.getClass() 一定不是java.sql.Connection)

(T) enhancer.create(new Class[] { java.sql.Connection.class}, 
                 new Object[] { connection }); 
tianpeng91
tianpeng91
额,,,我试了下,出了下面的异常,帮忙解决下,谢谢!
0
tianpeng91
tianpeng91
Exception in thread "main" net.sf.cglib.core.CodeGenerationException: java.lang.NoSuchMethodException-->net.sf.cglib.empty.Object$$EnhancerByCGLIB$$aecae9c4.<init>(java.sql.Connection)
	at net.sf.cglib.core.ReflectUtils.getConstructor(ReflectUtils.java:248)
	at net.sf.cglib.core.ReflectUtils.newInstance(ReflectUtils.java:220)
	at net.sf.cglib.proxy.Enhancer.createUsingReflection(Enhancer.java:636)
	at net.sf.cglib.proxy.Enhancer.firstInstance(Enhancer.java:538)
	at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:225)
	at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
	at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:304)
	at org.zhc.jdbc.BaseDAOProxy.getProxy(BaseDAOProxy.java:17)
	at org.zhc.jdbc.EntityManager.persist(EntityManager.java:84)
	at TestMYORM.main(TestMYORM.java:21)
Caused by: java.lang.NoSuchMethodException: net.sf.cglib.empty.Object$$EnhancerByCGLIB$$aecae9c4.<init>(java.sql.Connection)
	at java.lang.Class.getConstructor0(Unknown Source)
	at java.lang.Class.getDeclaredConstructor(Unknown Source)
	at net.sf.cglib.core.ReflectUtils.getConstructor(ReflectUtils.java:244)
	... 9 more


0
邸星星
邸星星
	@SuppressWarnings("unchecked")
	public <T> T getProxy(Class<T> clazz, Connection connection) {
		enhancer.setCallback(this);
            // 是不是要加这样一句??
            enhancer.setSuperclass(clazz);
	    ...
	}


邸星星
邸星星
@张浩春 客气了,只是刚刚用过cglib
tianpeng91
tianpeng91
谢谢,是对的,非常感谢!!!!!!!敢问大哥是不是架构师啊?
0
tianpeng91
tianpeng91
谢谢,是对的,非常感谢!!!!!!!敢问大哥是不是架构师啊?
0
walkingC
walkingC

你这是代理Connection和BaseDao有什么样的构造方法有什么关系啊?

返回顶部
顶部