2013-12-16 23 views
0

Iam是Spring框架的新蜜蜂,我指的是Spring項目提供的文檔。在使用@AspectJ風格學習SpringAOP時看到奇怪的行爲

在這個過程中,我也在學習一個新概念AOP。 我下面的春天文檔,嘗試一些樣品 http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html

我試圖用「@AspectJ」樣式使用Spring AOP我的第一個方面爲HelloWorld。

這是我的上下文配置文件

<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"); 

    } 



} 

這是我的實際INVOKER類

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) 

我試圖重新閱讀完整的頁面仍然我有同樣的問題也沒有得到足夠的材料處理最新的春季AOP樣品。所有在2002年或2008年的日期都有不同的解釋SpringAOP的方法。

有人可以幫助我理解我錯過這裏

感謝您的幫助

+0

Spring bean(及其代理)的實際類型是AOProgrammingInterface。這是從上下文獲取bean並使用它時應該使用的類型。 –

+0

感謝您的評論... –

回答

2

要理解這一點,你需要了解如何JDK proxies work and what their limitations are (and the alternative, CGLIB proxies)。簡而言之,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代理與類類型一起工作。

+0

感謝您的解釋。現在對我來說,理解AOP的概念是錯過了什麼。感謝您分享有關Proxy的鏈接。老實說很多學習... –

+0

@linux這將很快就值得:) –

+0

我有一個問題(如果它的愚蠢赦免),如果我的類實現兩個接口呢?哪一個我應該投給它? –