2010-02-10 21 views
7
<tx:advice id="txAdvice" transaction-manager="jtaTxManager"> 
    <tx:attributes> 
    <tx:method name="*" /> 
    </tx:attributes> 
</tx:advice> 

<aop:config proxy-target-class="true"> 
    <aop:pointcut id="fooServiceOperation" 
    expression="execution(* x.y.SampClass.save(..))" /> 
    <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation" /> 
</aop:config> 

<bean id="Samp1" class=" x.y.SampClass"></bean> 

     <bean id="SearchDispatchRpcGwtServlet" class="x.y.server.SearchDispatchRpcGwtServlet"> 
    <constructor-arg> 
     <list> 
     <ref bean="webServiceClient"/>       
     </list> 
    </constructor-arg>  
</bean> 

<!-- Service Clients --> 
<bean id="webServiceClient" class="x.y.KSBClientProxyFactoryBean"> 
    <property name="serviceEndpointInterface" value="x.y.service.WebService" /> 
    <property name="serviceQName" value="{http://x.y.org/wsdl/organization}WebService" /> 
</bean> 

Questa è la parte del file di contesto di esempio. Sto cercando di creare un avviso di transazione per SampClass da eseguire sul metodo di salvataggio.Spring Transaction - Confusione proxy

Quindi dalla mia comprensione dovrebbe creare un proxy solo per SampClass.

Ho un SearchDispatchRpcGwtServlet che accetta come argomento un client Webservice che è anche un proxy di per sé. Questo bean viene anche sottoposto a proxy per qualche motivo dove fallisce perché non può creare un proxy di un proxy.

Devo aggiungere che SearchDispatchRpcGwtServlet crea un'istanza di SampClass e chiama il metodo di salvataggio.

ottengo la seguente eccezione:

java.lang.IllegalArgumentException: Impossibile sottoclasse finale classe classe $ Proxy118 a net.sf.cglib.proxy.Enhancer.generateClass (Enhancer .java: 446) a net.sf.cglib.transform.TransformingClassGenerator. generateClass (TransformingClassGenerator.java:33)

Non capisco perché è sempre creato SearchDispatchRpcGwtServlet proxy. Qualcuno può spiegare.

aggiunta dello stack

Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class $Proxy117]: 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 $Proxy117 
    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:473) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:348) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:309) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:361) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean(AbstractAutowireCapableBeanFactory.java:1427) 
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport$1.run(FactoryBeanRegistrySupport.java:139) 
    ... 85 more 
Caused by: java.lang.IllegalArgumentException: Cannot subclass final class class $Proxy117 
    at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:446) 
    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) 
+0

Possiamo vedere più tracce dello stack? Quello che ci hai dato non è abbastanza. – skaffman

+0

Spiegherò il problema in modo più dettagliato. Ho un punto di taglio aop definito per Bean A. Ho Bean B definito dopo Bean A nel file di contesto. Da quello che immagino dovrebbe essere creato un proxy Bean. Ma in questo caso viene creato anche il proxy B B che contiene un proxy client webserivce come argomento. È un comportamento valido. Posso fare qualcosa per evitarlo. Il che significa che dovrebbe proxy solo il bean specificato. – nagl

+0

Ho aggiunto la traccia dello stack – nagl

risposta

1

una sottoclasse di AbstractAutoProxyCreator sta cercando di procura un fagiolo, ma che fagiolo è già in sé un proxy CGLIB creata usando un altro meccanismo, come aop:config proxy-target-class="true.

Per evitare questo, evitare di mescolare i diversi meccanismi di tessitura degli aspetti (ProxyBeanFactory e aop: config) per lo stesso bean.

In questo caso, gli aspetti della transazione possono anche essere intrecciati tramite <tx:annotation:driven/> tramite l'annotazione @Transactional.

In alternativa, è possibile rimuovere il trasferimento/scansione dal bean e eseguire l'iniezione delle dipendenze tramite XML utilizzando i setter.

Un'altra alternativa è quella di utilizzare il tempo di caricamento per tessere ovunque dichiarando <context:load-time-weaver/> e aggiungendo i barattoli necessari.

Dai un'occhiata anche a questo post, in generale sarebbe meglio usare solo un modo per applicare gli aspetti nell'intera applicazione, al fine di evitare questo problema.

+2

Autowiring non sta creando alcun proxy. –

+0

il 'AbstractAutowireCapableBeanFactory' che secondo javadoc fornisce il cablaggio (incluso autowiring) sta cercando di creare un proxy CGLIB tramite un processore bean, è nello stacktrace –

+3

No non è ... una sottoclasse di * AbstractAutoProxyCreator * sta cercando di creare il proxy. Questo post processore è probabilmente registrato dalla configurazione AOP. Il fatto che ci sia * AbstractAutowireCapableBeanFactory * sulla traccia dello stack è piuttosto irrilevante per il problema. La scansione automatica e la scansione dei componenti non sono collegate al proxy. –