2012-11-19 9 views
6

Stavo usando spring per creare oggetti tramite bean. Ora ho provato a utilizzare aop per creare lo stesso oggetto e ottengo $ Proxy non può essere lanciato per eccezione di SaleRoom.

xml precedente era:

<?xml version="1.0" encoding="UTF-8"?> 

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:aop="http://www.springframework.org/schema/aop/spring-aop-2.5.xsd" 
xmlns:context="http://www.springframework.org/schema/context/spring-context-2.5.xsd" 
xmlns:flow="http://www.springframework.org/schema/webflow-config/spring-webflow-config- 1.0.xsd" 
xmlns:jm s="http://www.springframework.org/schema/jms/spring-jms-2.5.xsd" 
xmlns:jee="http://www.springframework.org/schema/jee/spring-jee-2.5.xsd" 
xmlns:lang="http://www.springframework.org/schema/lang/spring-lang-2.5.xsd" 
xmlns:osgi="http://www.springframework.org/schema/osgi/spring-osgi.xsd" 
xmlns:tx="http://www.springframework.org/schema/tx/spring-tx-2.5.xsd" 
xmlns:util="http://www.springframework.org/schema/util/spring-util-2.5.xsd" 
xmlns:p="http://www.springframework.org/schema/p" 

xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  http://www.springframework.org/schema/aop/spring-aop-2.5.xsd/spring-spring-aop-2.5.xsd-2.5.xsd 
http://www.springframework.org/schema/context/spring-context-2.5.xsd  http://www.springframework.org/schema/context/spring-context-2.5.xsd/spring-spring-context-2.5.xsd-2.5.xsd 
http://www.springframework.org/schema/webflow-config/spring-webflow-config-1.0.xsd  http://www.springframework.org/schema/webflow-config/spring-webflow-config-1.0.xsd/spring-spring-webflow-config-1.0.xsd-2.5.xsd 
http://www.springframework.org/schema/jms/spring-jms-2.5.xsd  http://www.springframework.org/schema/jms/spring-jms-2.5.xsd/spring-spring-jms-2.5.xsd-2.5.xsd 
http://www.springframework.org/schema/jee/spring-jee-2.5.xsd  http://www.springframework.org/schema/jee/spring-jee-2.5.xsd/spring-spring-jee-2.5.xsd-2.5.xsd 
http://www.springframework.org/schema/lang/spring-lang-2.5.xsd  http://www.springframework.org/schema/lang/spring-lang-2.5.xsd/spring-spring-lang-2.5.xsd-2.5.xsd 
http://www.springframework.org/schema/osgi/spring-osgi.xsd  http://www.springframework.org/schema/osgi/spring-osgi.xsd/spring-spring-osgi.xsd-2.5.xsd 
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd  http://www.springframework.org/schema/tx/spring-tx-2.5.xsd/spring-spring-tx-2.5.xsd-2.5.xsd 
http://www.springframework.org/schema/util/spring-util-2.5.xsd  http://www.springframework.org/schema/util/spring-util-2.5.xsd/spring-spring-util-2.5.xsd-2.5.xsd 
"> 
<bean id="sale01" class="application.common.entities.BidRoom"> 
<property name="itemId" value="0001"/> 
<property name="lifeTime" value="15"/> 
</bean> 
</beans> 

e ho usato il seguente codice per creare le vendite:

ApplicationContext context = new FileSystemXmlApplicationContext(SalesManager.getSalesSourceFile()); 
    SaleRoom saleRoom; 
    List<String> salesNames = new LinkedList<String>(); 
    List<SaleRoom> allSales = new LinkedList<SaleRoom>(); 

    // Get all sales id's for beans 
    NodeList salesNodeList = salesDoc.getElementsByTagName("bean"); 

    for (int i = 0; i < salesNodeList.getLength(); i++) { 
     Node nNode = salesNodeList.item(i); 
     salesNames.add(((Element) nNode).getAttribute("id").toString()); 
    } 

    for (String saleName : salesNames) { 
     if(saleName.contains("sale")) { 
      saleRoom = (SaleRoom) context.getBean(saleName); 
      allSales.add(saleRoom); 
     } 
    } 

    return allSales; 

Questo è il nuovo xml:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:aop="http://www.springframework.org/schema/aop" 
      xsi:schemaLocation=" 
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"> 

    <aop:aspectj-autoproxy> 
     <aop:include name="logSettersCalls"/> 
    </aop:aspectj-autoproxy> 
    <bean id="logSettersCalls" class="application.logging.aop.LogSettersCalls"/> 

    <bean id="sale01" class="application.common.entities.BidRoom"> 
     <constructor-arg index="0" type="int" value="0001"/> 
     <constructor-arg index="1" type="int" value="15"/> 
    </bean> 
</beans> 

La registrazione Aspect classe:

@Aspect 
public class LogSettersCalls { 
    @Pointcut("execution(void set*(*))") 
    public void setMethod() {} 

    @Before("setMethod()") 
    public void logSetterCall(JoinPoint theJoinPoint) { 
     String methodName = theJoinPoint.getSignature().getName(); 
     Object newValue = theJoinPoint.getArgs()[0]; 
     Object theObject = theJoinPoint.getTarget(); 
     System.out.println("The method " + methodName + " is called on object " 
       + theObject + " with the value " + newValue); 
    } 
} 

Sto usando lo stesso codice per creare i bean via aop. e ottengo Exception in thread "main" java.lang.ClassCastException: $ Proxy11 non può essere lanciato a application.common.entities.SaleRoom

La linea che genera l'eccezione: saleroom = (saleroom) context.getBean (saleName);

Qualsiasi aiuto sarà apprezzato. Grazie.

risposta

36

La classe SaleRoom implementa un'interfaccia? Se sì, allora si dovrebbe usare l'interfaccia e non di classe in te codice:

ISaleRoom saleRoom = (ISaleRoom) context.getBean(saleName); 

Perché se il bean implementa alcune interfaccia poi molla per default creerà delega sulla base di questa interfaccia.

Ecco a good article about proxy creation in Spring.

Inoltre è possibile modificare il proxy meccanismo per la primavera AOP se si desidera creare proxy per classe di destinazione. Questo è descritto here in reference documentation.

+0

My SaleRoom estende Thread e non implementa alcuna interfaccia. – Tsikon

+2

Penso che il motivo del problema è che Thread implementa Runnable. Prova a creare la tua interfaccia aziendale (ad esempio ISaleRoom) dove definire i metodi di business a cui devi accedere. Quindi nel cast di codice dell'interfaccia (ISaleRoom) context.getBean (saleName) come ho menzionato nella risposta. – dimas

+0

Oppure puoi provare a cambiare il meccanismo di proxy (guarda il link che ho postato). – dimas