Code Bye

向大神求教,Spring 使用 cglib动态代理问题

我要使用spring的AOP做操作日志功能,想代理springmvc的controller

如果使用jdk自带的代理,目标类就必须实现某个接口,对controller不适用。

如果使用cglib,由于我数据访问层使用的是mybatis,自动生成的mapper,没有默认的构造方法,cglib要求代理的目标类要有默认的构造方法,启动就报错了。

请问大神们有碰到这种问题吗,能不能给个解决思路。

<aop:aspectj-autoproxy proxy-target-class=”true”/>,加上红色部分,就是使用cglib代理了,否则使用jdk的默认代理。

报错内容如下:
Error creating bean with name “”userMapper””: Post-processing of the FactoryBean””s object failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy22]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy22

求大神来看看啊
千万别沉啊,等解决啊

20分
proxy-target-class=”true” 是强制使用CGLIB生成代理
去掉这个试试呢?
引用 3 楼 zaxer 的回复:

proxy-target-class=”true” 是强制使用CGLIB生成代理
去掉这个试试呢?

去掉这个没有问题,但是不能对controller代理,jdk的默认代理必须要目标类实现接口。

mapper 是什么? controller么? 配置发出来看下
引用 5 楼 whos2002110 的回复:

mapper 是什么? controller么? 配置发出来看下

mapper:

public interface UserMapper extends IBaseMapper<UserExample, User, Integer> {
}

IBaseMapper:

package com.szyungu.ecommunity.base.service;

import java.util.List;
import org.apache.ibatis.annotations.Param;

public interface IBaseMapper<C,R,PK> {

	int countByCondition(C condition);

	int insert(R record);

	int insertSelective(R record);

    int updateByPrimaryKeySelective(R record);

	int updateByPrimaryKey(R record);
    
    int updateByConditionSelective(@Param("record") R record, @Param("example") C condition);

    int updateByCondition(@Param("record") R record, @Param("example") C condition);

    int deleteByCondition(C condition);

    int deleteByPrimaryKey(PK id);
    
    R selectByPrimaryKey(PK id);

    List<R> selectByCondition(C condition);   
}

controller:
就是普通的spring mvc的controller


20分
引用 6 楼 lookthatgirl 的回复:
Quote: 引用 5 楼 whos2002110 的回复:

mapper 是什么? controller么? 配置发出来看下

mapper:

public interface UserMapper extends IBaseMapper<UserExample, User, Integer> {
}

IBaseMapper:

package com.szyungu.ecommunity.base.service;

import java.util.List;
import org.apache.ibatis.annotations.Param;

public interface IBaseMapper<C,R,PK> {

	int countByCondition(C condition);

	int insert(R record);

	int insertSelective(R record);

    int updateByPrimaryKeySelective(R record);

	int updateByPrimaryKey(R record);
    
    int updateByConditionSelective(@Param("record") R record, @Param("example") C condition);

    int updateByCondition(@Param("record") R record, @Param("example") C condition);

    int deleteByCondition(C condition);

    int deleteByPrimaryKey(PK id);
    
    R selectByPrimaryKey(PK id);

    List<R> selectByCondition(C condition);   
}

controller:
就是普通的spring mvc的controller

那你这个userMapper在代理中是什么角色呢? 就是他跟controller什么关系?  
你这错误:Error creating bean with name “”userMapper””: Post-

没搞清楚你是要代理什么?  配置发出来看看

如果你要代理controller, 在spring mvc的配置文件里面配下aop代理就好了呀
引用 8 楼 whos2002110 的回复:

如果你要代理controller, 在spring mvc的配置文件里面配下aop代理就好了呀

谢谢!
原因是使用了:

<aop:aspectj-autoproxy proxy-target-class="true"/>

配置proxy-target-class=”true”则强制使用了CGLIB生成代理,mybatis的mapper没有默认构造方法,会报错:

 Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy22]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy22

修改成
<aop:aspectj-autoproxy/>
这个的意思我原本以为是完全不使用cglib的代理,现在发现应该是spring会自动在JDK动态代理和CGLIB之间转换。

谢谢大家的热心帮助,现在问题解决了,多谢大家!@whos2002110,@EggItayi 

引用 3 楼 zaxer 的回复:

proxy-target-class=”true” 是强制使用CGLIB生成代理
去掉这个试试呢?

非常感谢你,你说的是对的,我一开始没有完全理解你的意思,我被自己的认知套住了。


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明向大神求教,Spring 使用 cglib动态代理问题