线程“main”中的异常 java.lang.ClassCastException: com.sun.proxy.$Proxy13 cannot be cast to CustomeClass

问题描述 投票:0回答:1

我正在尝试使用 Spring Framework 学习 AOP,但有一个异常一直被调用。

错误:线程“main”中的异常 java.lang.ClassCastException: com.sun.proxy.$Proxy13 无法转换为 com.controller.Triangle

Shape.java

package com.controller;

public interface Shape {
    public void draw();
}

三角.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"); }
    }

在主要方法里面

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> 

请任何人帮忙。

spring spring-aop
1个回答
1
投票

感谢 MCVE,现在很容易重现您的问题并验证修复。只是阅读代码但无法运行它并没有让我发现问题。

很简单:你的建议

beforeMeth()
必须公开。然后一切都像魅力一样。


更新:

好吧,我想我知道你缺少什么。您正在将创建的 bean 转换为

Triangle
,但这不是一个接口而是一个类,因此如果没有进一步的配置,它不能被 Spring AOP 代理。所以你在这里有两个选择:

  • 或者你只是将代码更改为

    Shape tr = (Shape) appContext.getBean("triangle");
    以便转换为Spring自动使用的接口以创建JDK动态代理。

  • 或者您通过

    <aop:aspectj-autoproxy proxy-target-class="true"/>
    使用 CBLIB 启用类代理。当然,您也可以使用
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    代替。

现在这是一个同时显示两种方法的解决方案。可以通过改变

XML_CONFIG
的值来切换。

顺便说一句,我还将您的包名称

com.AOP
更正为
com.aop
(小写字符是包的默认字符),并将您的方面名称从
myCustomAspect
更正为
MyCustomAspect
(Java 类应以大写字符开头).我也将
Spring.xml
重命名为
spring.xml
。在接口中,你不需要
public
方法声明,因为根据定义,所有接口方法都是公共的。但所有这些都只是表面功夫,真正的解决办法是上面那个。

所以这是你的改进代码:

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> 
© www.soinside.com 2019 - 2024. All rights reserved.