Exception in thread “main” java.lang.ClassCastException: com.sun.proxy.$Proxy13 cannot be cast to CustomeClass

匿名 (未验证) 提交于 2019-12-03 10:24:21

问题:

I am trying to learn AOP with Spring Framework, but there is one exception that keeps on getting invoked.

Error : Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy13 cannot be cast to com.controller.Triangle

Shape.java

package com.controller;  public interface Shape {     public void draw(); } 

Triangle.java

package com.controller; import org.springframework.stereotype.Component;  @Component public class Triangle implements Shape {         public void draw()         {                System.out.println("this draw method of triangle"),         } } 

myCustomAspect.java

    package com.AOP;      import org.aspectj.lang.annotation.After;     @EnableAspectJAutoProxy     @Component     @Aspect     public class myCustomAspect {          @Pointcut("execution(* *.draw())")         private void pop(){}          @Before("pop()")         private void beforeMeth(){             System.out.println("this is before draw"); }     } 

inside main method

ApplicationContext  ssp = new ClassPathXmlApplicationContext("/Spring.xml"); Shape tr=(Triangle)ssp.getBean("triangle"); tr.draw(); 

Spring.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:context="http://www.springframework.org/schema/context"          xmlns:aop = "http://www.springframework.org/schema/aop"          xmlns:tx="http://www.springframework.org/schema/tx"         xsi:schemaLocation="http://www.springframework.org/schema/beans             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd             http://www.springframework.org/schema/context             http://www.springframework.org/schema/context/spring-context-3.0.xsd             http://www.springframework.org/schema/aop              http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">       <context:annotation-config></context:annotation-config>     <context:component-scan base-package="com.controller,com.AOP"></context:component-scan> </beans>  

Please any one help.

回答1:

Thanks for the MCVE, now it was easy to recreate your problem and verify the fix. Just reading the code and not being able to run it did not make me spot the problem.

It is very simple: Your advice beforeMeth() must be public. Then everything works like a charm.


Update:

Okay, I think I know what is missing on your part. You are casting the created bean to Triangle, but that is not an interface but a class, thus it cannot be proxied by Spring AOP without further configuration. So you have two options here:

  • Either you just change the code to Shape tr = (Shape) appContext.getBean("triangle"); so as to cast to the interface that is automatically used by Spring in order to create the JDK dynamic proxy.

  • Or you enable class proxying with CBLIB via <aop:aspectj-autoproxy proxy-target-class="true"/>. You can also use @EnableAspectJAutoProxy(proxyTargetClass = true) instead, of course.

Now here is a solution showing both approaches in parallel. You can switch by changing the value of XML_CONFIG.

BTW, I also corrected your package name com.AOP to com.aop (lower-case characters are the default for packages) and your Aspect name from myCustomAspect to MyCustomAspect (Java classes should start with an upper-case character). I also renamed Spring.xml to spring.xml. And in tnterfaces you do not need public for method declarations because all interface methods are by definition public. But all of this is just cosmetics, the real fix is the one above.

So here is your improved code:

package com.controller;  public interface Shape {   void draw(); } 
package com.controller;  import org.springframework.stereotype.Component;  @Component public class Triangle implements Shape {   public void draw() {     System.out.println("this draw method of triangle");   } } 
package com.aop;  import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.stereotype.Component;  @Component @Aspect public class MyCustomAspect {   @Pointcut("execution(* *.draw())")   private void pop() {}    @Before("pop()")   public void beforeMeth() {     System.out.println("this is before draw");   } } 
package de.scrum_master.app;  import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.support.ClassPathXmlApplicationContext;  import com.controller.Shape; import com.controller.Triangle;  @Configuration @EnableAspectJAutoProxy(proxyTargetClass = true) @ComponentScan(basePackages = { "com.controller", "com.aop" }) public class Application {   private static final boolean XML_CONFIG = true;   public static void main(String[] args) {     ApplicationContext appContext =  XML_CONFIG       ? new ClassPathXmlApplicationContext("/spring.xml")       : new AnnotationConfigApplicationContext(Application.class);     Shape tr = (Triangle) appContext.getBean("triangle");     tr.draw();   } } 
<?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:context="http://www.springframework.org/schema/context"   xmlns:aop="http://www.springframework.org/schema/aop"   xmlns:tx="http://www.springframework.org/schema/tx"   xsi:schemaLocation="     http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd     http://www.springframework.org/schema/context     http://www.springframework.org/schema/context/spring-context-3.0.xsd     http://www.springframework.org/schema/aop      http://www.springframework.org/schema/aop/spring-aop-3.0.xsd   ">    <context:component-scan base-package="com.controller,com.aop"></context:component-scan>   <aop:aspectj-autoproxy proxy-target-class="true"/> </beans>  


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!