当前位置: 首页 > 知识库问答 >
问题:

使用@AspectJ风格学习SpringAOP时看到奇怪的行为

沈凡
2023-03-14

我是一个新的bee-to-Spring框架,我指的是Spring项目中可用的文档。

在这个过程中,我还学习了一个新概念AOP。我遵循spring文档来尝试一些示例http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html

我尝试使用Spring AOP为我的第一个Aspect Helloworld使用“@AeyJ”样式。

这是我的上下文配置文件

<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" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context.xsd">

     <aop:aspectj-autoproxy expose-proxy="false" />

    <context:annotation-config></context:annotation-config>

    <bean id="aoProgrammingAspectJ" class = "com.AOProgramming.AOProgrammingAspectJ">
    </bean>


    <bean id="aoProgrammingImpl" class = "com.AOProgramming.AOProgrammingImpl">
    </bean>

</beans>

这是一个简单的界面

package com.AOProgramming;

public interface AOProgrammingInterface {

    public void startAspecting();

}

我实现这个接口

package com.AOProgramming;

public class AOProgrammingImpl implements AOProgrammingInterface {


    @Override
    public void startAspecting() {

        System.out.println("THe Aspecting has just begun for :");

    }
}

这就是我为切入点和建议定义方面定义的地方

package com.AOProgramming;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;


@Aspect
public class AOProgrammingAspectJ {

    @Pointcut("execution( * com.AOProgramming.*.*(..))")
    public void cuttingOne() {}

    @Before("cuttingOne()")
    public void adviceCuttingOne1(){

        System.out.println("This is the at the beginning");

    }



}

这是我实际的调用器类

package com.AOProgramming;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AOProgrammingInvokerApp {

    public static void main(String[] args){

        ApplicationContext context = new ClassPathXmlApplicationContext("AOProgramming-servlet.xml");

        AOProgrammingImpl obj = (AOProgrammingImpl) context.getBean("aoProgrammingImpl");

        obj.startAspecting();

    }

}

当我试图执行样本时,我得到了以下错误

Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy6 cannot be cast to com.AOProgramming.AOProgrammingImpl
    at com.AOProgramming.AOProgrammingInvokerApp.main(AOProgrammingInvokerApp.java:12)

我试图重新阅读完整的页面,但我仍然有同样的问题,也没有获得足够的材料处理最新的SpringAOP样本。所有这些都可以追溯到2002年或2008年,这对SpringAOP有不同的解释方式。

有人能帮我理解我错过了什么吗

谢谢你的帮助

共有1个答案

贾兴学
2023-03-14

要理解这一点,您需要了解JDK代理是如何工作的,以及它们的局限性是什么(以及CGLIB代理)。简而言之,JDK代理只保留目标bean接口的类型。因此,为AOProgrammingImpl生成的代理将是AOProgrammingInterface类型,而不是AOProgrammingImpl类型,即使目标是AOProgrammingImpl类型。

你可以改变这个

AOProgrammingImpl obj = (AOProgrammingImpl) context.getBean("aoProgrammingImpl");

到这个

AOProgrammingInterface obj = (AOProgrammingInterface) context.getBean("aoProgrammingImpl");

或者,您可以将CGLIB添加到类路径,并将配置更改为

<aop:aspectj-autoproxy expose-proxy="false" proxy-target-class="true" />

因此Spring使用与类类型一起工作的CGLIB代理。

 类似资料:
  • 我正在使用Mapstruct映射将一个POJO转换为另一个POJO模型 以下是mapstruct自动生成的方法 该方法基本上获取源POJO的映射,并将其转换为目标模型的映射。生成正在通过。 当我运行代码时,我在这个方法中得到了ClassCast异常:HeaderAttributeGenericDataTypeMaptoStringEnergiectAttributeDataMap 堆栈跟踪: 我还

  • 我有以下代码来解析一个JSON文件: 要处理以下JSON文件: 如果我执行此代码,我将收到以下错误: 所以我开始一步一步地调试应用程序,看看part processing()中的哪个代码部分抛出了这个异常。令人惊讶的是,那里的所有代码都正常执行:没有抛出异常,也没有返回结果I except。 更让我惊讶的是,当我稍微改变第一种方法的代码时,它可以在不产生异常的情况下工作。 我不知道println方

  • 问题内容: 请考虑以下示例Java类(下面的pom.xml): 我写一个FileOutputStream,然后尝试删除该文件, 而不先关闭Stream 。这是我最初的问题,当然是错误的,但它导致了一些奇怪的发现。 在Windows 7上运行主方法时,它将产生以下输出: 为什么第一次调用Files.delete()不会引发异常? 为什么以下对Files.exist()的调用返回false? 为什么无

  • 这个程序打印00,但是如果我注释掉a.store和b.store,而取消注释a.fetch_add和b.fetch_add,这做了完全相同的事情,即都设置了a=1,b=1的值,我永远不会得到00。 是我错过了什么,还是“00”按标准永远不会出现? 下面打印00。 下图从不打印00 再看看这个,多线程原子a b打印00 for memory_order_refield

  • 我有以下代码: 假设我现在将电脑的时区设置为太平洋时间(PDT为UTC-7),则打印 2012年6月29日星期五08:15:00太平洋标准时间 PDT不是比IST(印度标准时间)晚12.5小时吗?这个问题在任何其他时区都不会发生-我尝试了UTC、PKT、MMT等,而不是日期字符串中的IST。Java中有两个IST吗? 注意:实际代码中的日期字符串来自外部源,因此我不能使用GMT偏移量或任何其他时区

  • 问题内容: 我正在使用jmh 使用maven并按照http://openjdk.java.net/projects/code- tools中 建议的命令行方法对一个简单的应用程序进行基准测试。成功设置并建立基准后,我可以使用avgt模式获得以下基准结果: 我不确定如何解释此输出,但我确定某些地方出了错…?知道什么或如何调试吗? 问题答案: JMH输出使用扩展的Unicode字符。特别是, ?10