使用Pointcut与javax.sql.DataSource.getConnection(..)

时间:2016-06-08 20:42:41

标签: java spring websphere spring-aop spring-aspects

我尝试通过在获取数据库连接后调用 DBMS_SESSION.SET_IDENTIFIER('XXXX')过程来设置 ClientIdentifier 值。为了实现这一点,我使用了 Spring AOP方面,如链接中所述:http://docs.spring.io/spring-data/jdbc/docs/current/reference/html/orcl.connection.html 下面是我所拥有的一段代码:

@Aspect
public class ClientIdentifierConnectionPreparer {

@AfterReturning(pointcut= "execution(* javax.sql.DataSource.getConnection(..))",
        returning = "connection")
public Connection setClientIdentifier(Connection connection) throws SQLException {
    CallableStatement cs=connection.prepareCall("{call DBMS_SESSION.SET_IDENTIFIER('XXXX')}");
    cs.execute();
    cs.close();
    return connection;

我在spring配置xml文件中配置了 aop autoaspect proxy

<aop:aspectj-autoproxy />

<bean id="connectionPreparer" 
    class="xx.xxxx.xxxx.xxxx.xxxx.ClientIdentifierConnectionPreparer" />

我正在使用 web sphere应用程序服务器来部署应用程序,我已按照链接http://www.ibm.com/support/knowledgecenter/was_beta/com.ibm.websphere.base.doc/ae/tspr_config_data_access.html中的指定配置了数据源 当我部署我的应用程序时,我遇到了错误。似乎Spring错误地尝试转换/子类,这是最终的并且遇到了cglib代理问题。如果我使用其他连接池提供程序数据源配置而不是 Web sphere JNDI数据源,则evrything似乎正常工作。我尝试过 org.apache.commons.dbcp.BasicDataSource ,我能够成功设置客户端标识符值。 下面是我用web sphere JNDI数据源得到的错误:

    DEBUG - Creating instance of bean 'sessionFactory'
DEBUG - Eagerly caching bean 'sessionFactory' to allow for resolving potential circular references
DEBUG - Returning cached instance of singleton bean 'dataSource'
DEBUG - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
DEBUG - Returning cached instance of singleton bean 'org.springframework.aop.aspectj.AspectJPointcutAdvisor#0'
DEBUG - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
DEBUG - Returning cached instance of singleton bean 'org.springframework.aop.aspectj.AspectJPointcutAdvisor#0'
DEBUG - Creating implicit proxy for bean 'dataSource' with 0 common interceptors and 2 specific interceptors
DEBUG - Creating CGLIB proxy: target source is SingletonTargetSource for target object [com.sun.proxy.$Proxy134@df1d109a]
WARN  - Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.equals(java.lang.Object)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final int com.sun.proxy.$Proxy134.hashCode()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final java.lang.String com.sun.proxy.$Proxy134.toString()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.isPreFiltered()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final java.io.PrintWriter com.sun.proxy.$Proxy134.getLogWriter() throws java.sql.SQLException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.isProxyTargetClass()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.isFrozen()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.setLogWriter(java.io.PrintWriter) throws java.sql.SQLException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final java.lang.Object com.sun.proxy.$Proxy134.unwrap(java.lang.Class) throws java.sql.SQLException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.removeAdvice(org.aopalliance.aop.Advice)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.removeAdvisor(org.springframework.aop.Advisor)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.setExposeProxy(boolean)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final int com.sun.proxy.$Proxy134.indexOf(org.springframework.aop.Advisor)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final java.lang.Class com.sun.proxy.$Proxy134.getTargetClass()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final org.springframework.aop.TargetSource com.sun.proxy.$Proxy134.getTargetSource()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final int com.sun.proxy.$Proxy134.getLoginTimeout() throws java.sql.SQLException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.addAdvisor(int,org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.isExposeProxy()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.addAdvisor(org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.isWrapperFor(java.lang.Class) throws java.sql.SQLException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final java.sql.Connection com.sun.proxy.$Proxy134.getConnection() throws java.sql.SQLException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.addAdvice(int,org.aopalliance.aop.Advice) throws org.springframework.aop.framework.AopConfigException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.setLoginTimeout(int) throws java.sql.SQLException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final java.lang.Class[] com.sun.proxy.$Proxy134.getProxiedInterfaces()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.removeAdvisor(int) throws org.springframework.aop.framework.AopConfigException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final java.sql.Connection com.sun.proxy.$Proxy134.getConnection(java.lang.String,java.lang.String) throws java.sql.SQLException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final int com.sun.proxy.$Proxy134.indexOf(org.aopalliance.aop.Advice)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.setPreFiltered(boolean)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.replaceAdvisor(org.springframework.aop.Advisor,org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
Unable to proxy method [public final org.springframework.aop.Advisor[] com.sun.proxy.$Proxy134.getAdvisors()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.isInterfaceProxied(java.lang.Class)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.addAdvice(org.aopalliance.aop.Advice) throws org.springframework.aop.framework.AopConfigException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final java.util.logging.Logger com.sun.proxy.$Proxy134.getParentLogger() throws java.sql.SQLFeatureNotSupportedException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final java.lang.String com.sun.proxy.$Proxy134.toProxyConfigString()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.setTargetSource(org.springframework.aop.TargetSource)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
DEBUG - Retrieved dependent beans for bean '(inner bean)#ca01323a': [org.springframework.aop.aspectj.AspectJPointcutAdvisor#0]
Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@184af104: 
defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,
org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,
org.springframework.context.annotation.internalPersistenceAnnotationProcessor,transitionController,dataSource,
sessionFactory,transactionManager,persistenceExceptionTranslationPostProcessor,
org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,
org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor
org.springframework.aop.aspectj.AspectJPointcutAdvisor#0,
pointCut,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor]; 
root of factory hierarchy
Retrieved dependent beans for bean '(inner bean)#c0432d95': [(inner bean)#ca01323a]
 ERROR - Context initialization failed
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [sessionfactory.xml]: Cannot resolve reference to bean 'dataSource' while setting bean property 'dataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource': 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.$Proxy134]: 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.$Proxy134
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:336)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1456)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1197)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
    ... 129 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource': 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.$Proxy134]: 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.$Proxy134
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:167)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:103)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1514)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:252)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
    ... 139 more
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy134]: 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.$Proxy134
    at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:212)
    at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:109)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:494)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:379)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:339)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:421)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean(AbstractAutowireCapableBeanFactory.java:1698)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:164)
    ... 144 more
Caused by: java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy134
    at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:446)
    at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
    at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
    at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
    at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
    at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
    at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:57)
    at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:202)
    ... 151 more

我还尝试使用 proxy target = true和false 来强制使用JDK动态代理而不是cglib创建代理。但在两种方式中它都使用cglib代理。

有人见过这类错误。有人可以查看错误,并告诉我是否有任何其他替代解决方案可以解决此错误。

更新: 添加JNDI配置。 我在web.xml文件中定义了resource-ref

<resource-ref>
<res-ref-name>jdbc/springdbres-ref-name>jdbc/myDS>
<res-type>javax.sql.DataSourceres-type>javax.sql.DataSource>
<res-auth>Containerres-auth>Container>
<res-sharing-scope>Shareableres-sharing-scope>Shareable>
</resource-ref>

我定义了数据源bean和jndi查找配置如下:

    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/jdbc/myDS"/>
    <property name="lookupOnStartup" value="false"/>
    <property name="cache" value="true"/>
    <property name="proxyInterface" value="javax.sql.DataSource"/>
</bean>

    <jee:jndi-lookup id=" dataSource"
    jndi-name="jdbc/myDS"
    cache="true"
    resource-ref="true"
    lookup-on-startup="false"
    proxy-interface="javax.sql.DataSource"/>

0 个答案:

没有答案