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

发布于 2021-11-21 02:02:22 字数 2672 浏览 761 评论 10

我想自己做一套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;
	}

}

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

时光清浅 2021-11-21 02:13:27

@张浩春 客气了,只是刚刚用过cglib

谁的新欢旧爱 2021-11-21 02:13:27

谢谢,是对的,非常感谢!!!!!!!敢问大哥是不是架构师啊?

累赘 2021-11-21 02:13:27

谢谢,是对的,非常感谢!!!!!!!敢问大哥是不是架构师啊?

离不开的别离 2021-11-21 02:13:27

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

伪装你 2021-11-21 02:13:26
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

混吃等死 2021-11-21 02:13:26
	@SuppressWarnings("unchecked")
	public <T> T getProxy(Class<T> clazz, Connection connection) {
		enhancer.setCallback(this);
            // 是不是要加这样一句??
            enhancer.setSuperclass(clazz);
	    ...
	}

飘过的浮云 2021-11-21 02:13:21

 

(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 }); 
深巷少女 2021-11-21 02:13:21

额,,,我试了下,出了下面的异常,帮忙解决下,谢谢!

奢华的一滴泪 2021-11-21 02:13:16

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

这个是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来实现带参的构造函数动态代理,谢谢了!!!

海之角 2021-11-21 02:12:39

由于代码较多,我在上面贴了相关代码,麻烦解答下,谢谢!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文