iteye_17320 2008-11-30 23:26
浏览 533
已采纳

通过CGLIB进行构造函数注入时,AOP引发异常

(感觉这个问题虽然是个纯技术问题,但最好发到论坛里问问,因为俺在网上查了好半天也没查到解决方法。如果非要给俺整到“问答”里,俺也没脾气。)





现象描述

Struts2 + Spring,Action中注入Service,Service中注入Dao。

Service中并没有使用接口,根据网上资料,应是使用CGLIB来创建类对象。

此前,使用Set注入时,没有任何问题,一切正常。

前两天看了一下Spring in Action,对于Dao注入Service时,通过构造函数注入比较不错。

今晚改成通过构造函数注入时,发生了异常,由于对CGLIB的加载对象的过程不太了解,原因实现查不明白,各位请帮帮忙吧。



具体实现



Service类的实现

public class UserService {

private IUserDao userDao;

public UserService(IUserDao userDao) {
    this.userDao = userDao;
}

}





applicationContext.xml的配置

 <!---->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="WEB-INF/SqlMapConfig.xml">
<property name="dataSource" ref="dataSource">
</bean>
<!---->
&lt;bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt;
    &lt;property name="dataSource"&gt;
        &lt;ref local="dataSource"&gt;
    &lt;/property&gt;
&lt;/bean&gt;

<!---->
&lt;aop:config proxy-target-class="true"&gt;
    &lt;aop:pointcut id="serviceOperation" expression="execution(* cn.ipcat.service.*.*(..))"&gt;
    &lt;aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice"&gt;
&lt;/aop:config&gt;

<!---->
&lt;tx:advice id="txAdvice" transaction-manager="transactionManager"&gt;
    &lt;tx:attributes&gt;
        <!---->
        &lt;tx:method name="save*" rollback-for="Exception"&gt;
        <!---->
        &lt;tx:method name="insert*" rollback-for="Exception"&gt;
        &lt;tx:method name="create*" rollback-for="Exception"&gt;
        <!---->
        &lt;tx:method name="update*" rollback-for="Exception"&gt;
        <!---->
        &lt;tx:method name="delete*" rollback-for="Exception"&gt;
        <!---->
        &lt;tx:method name="*" read-only="true" rollback-for="Exception"&gt;
    &lt;/tx:attributes&gt;
&lt;/tx:advice&gt;

<!---->
&lt;bean id="userDao" class="cn.ipcat.entity.user.UserDao"&gt;
    &lt;property name="sqlMapClient"&gt;
        &lt;ref bean="sqlMapClient"&gt;&lt;/ref&gt;
    &lt;/property&gt;
&lt;/bean&gt;

<!---->
&lt;bean id="userService" class="cn.ipcat.service.UserService"&gt;
    &lt;constructor-arg&gt;
        &lt;ref bean="userDao"&gt;
    &lt;/constructor-arg&gt;
&lt;/bean&gt;</pre>




struts.xml的配置

略。



我个人的测试分析

我试验了一下,只要在applicationContext.xml中不加下段记述就没事,一旦加了,就出错。

考虑,可能是“aop:pointcut”的“expression”的问题,分析可能是通过带参数的构造函数生成对象时,进行切面控制,从而导致问题,但是为什么通过Set方式注入时就没事,没想明白。

如果真的是“expression”的问题,那么对于带参数的构造函数,这里应该怎么写呢?



 <!---->
<aop:config proxy-target-class="true">
<aop:pointcut id="serviceOperation" expression="execution(* cn.ipcat.service.*.*(..))">
<aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice">
</aop:config>




具体的错误信息

在tomcat一启动时,预加载各个类对象时,就出错了。



信息: Initializing Spring root WebApplicationContext
[ERROR]_2008-11-30 22:27:27_org.springframework.web.context.ContextLoader@(ContextLoader.java:215):Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService' defined in ServletContext resource [/WEB-INF/appcontext/UserAppContext.xml]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class cn.ipcat.service.UserService]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:221)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:729)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:381)
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3843)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4342)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
at org.apache.catalina.core.StandardService.start(StandardService.java:516)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class cn.ipcat.service.UserService]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:213)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:110)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:488)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:363)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:324)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:361)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1343)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
... 29 more
Caused by: java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
at net.sf.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:721)
at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:499)
at net.sf.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)
at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:201)
... 36 more
2008-11-30 22:27:27 org.apache.catalina.core.StandardContext listenerStart
严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService' defined in ServletContext resource [/WEB-INF/appcontext/UserAppContext.xml]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class cn.ipcat.service.UserService]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:221)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:729)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:381)
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3843)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4342)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
at org.apache.catalina.core.StandardService.start(StandardService.java:516)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class cn.ipcat.service.UserService]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:213)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:110)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:488)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:363)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:324)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:361)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1343)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
... 29 more
Caused by: java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
at net.sf.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:721)
at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:499)
at net.sf.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)
at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:201)
... 36 more
2008-11-30 22:27:27 org.apache.catalina.core.StandardContext start
严重: Error listenerStart
2008-11-30 22:27:27 org.apache.catalina.core.StandardContext start
严重: Context [] startup failed due to previous errors
2008-11-30 22:27:27 org.apache.catalina.core.ApplicationContext log
信息: Closing Spring root WebApplicationContext
  • 写回答

1条回答 默认 最新

  • jackjc 2008-12-01 20:11
    关注

    UserService里面加上 [code="java"]public UserService();[/code]试试看

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?