2016-11-28 123 views
-2

我找不到任何回答此問題的文檔。在Spring 4中,代理問題是否得到妥善處理?

總結:

  • 我有實現接口的bean。
  • 我將proxy-target-class設置爲false。
  • 我在Spring 3.2.17和4.3.3版本之間切換。
  • 當我使用Spring 3.2.17,主類拋出這樣的:

    java.lang.ClassCastException:com.sun.proxy $ Proxy7不能在COM被轉換爲 com.package1.Camera 。 package1.App.main(App.java:8)

    這是我的預期。這是正確的行爲,因爲JDK代理類已生成。

  • 但是,當我使用Spring 4.3.3時,沒有引發異常,主類正常運行。

    CGLIB代理類已生成。但是爲什麼當我將proxy-target-class設置爲false時會產生這種情況?

這裏是源文件:

App.java

package com.package1; 

import org.springframework.context.support.ClassPathXmlApplicationContext; 

public class App { 
    public static void main(String[] args) { 
     ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); 
     Camera camera = (Camera) context.getBean("camera"); 
     camera.snap(); 
     context.close(); 
    } 
} 

ICamera.java

package com.package1; 
public interface ICamera {} 

Camera.java

package com.package1; 

import org.springframework.stereotype.Component; 

@Component("camera") 
public class Camera implements ICamera { 
    public void snap() { 
     System.out.println("SNAP!"); 
    } 
} 

Logger.java

package com.package1; 

import org.aspectj.lang.annotation.Aspect; 
import org.aspectj.lang.annotation.Before; 
import org.aspectj.lang.annotation.Pointcut; 
import org.springframework.stereotype.Component; 

@Aspect 
@Component 
public class Logger { 

    @Pointcut("execution(void com.package1.Camera.snap())") 
    public void cameraSnap() { 

    } 

    @Before("cameraSnap()") 
    public void beforeAdvice() { 
     System.out.println("Before advice..."); 
    } 

} 

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


    <context:component-scan 
     base-package="com.package1"> 
    </context:component-scan> 

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

</beans> 

的pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>com.package1</groupId> 
    <artifactId>spring-test-app</artifactId> 
    <version>0.0.1-SNAPSHOT</version> 
    <dependencies> 
    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-core</artifactId> 
     <version>4.3.3.RELEASE</version> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-beans</artifactId> 
     <version>4.3.3.RELEASE</version> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-context-support</artifactId> 
     <version>4.3.3.RELEASE</version> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-aspects</artifactId> 
     <version>4.3.3.RELEASE</version> 
    </dependency> 
    </dependencies> 
</project> 
+0

它甚至是一個代理...我沒有看到任何方面...沒有任何方面匹配,沒有代理,沒有錯誤... –

+0

我不知道爲什麼,但此代碼仍然工作。 –

+0

你可以在這裏查看我的代碼:https://github.com/tuyendev/SpringCore/tree/master/Example/SpringCore –

回答

0

直通試驗和錯誤我想出了答案。

App.java

package com.package1; 

import org.springframework.context.support.ClassPathXmlApplicationContext; 

public class App { 
    public static void main(String[] args) { 
     ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); 
     Object o = context.getBean("camera"); 
     System.out.println("class=" + o.getClass()); 
     Camera camera = (Camera) context.getBean("camera"); 
     camera.snap(); 
     context.close(); 
    } 
} 

代理目標類仍然默認爲false。但是現在,Spring 4已經足夠智能了,它將生成哪種代理(JDK或CGLIB)。

  • 如果您有一個空接口,它將生成一個CGLIB代理。

ICamera.java

package com.package1; 
public interface ICamera {} 
  • 否則,JDK代理將會產生。

ICamera.java

package com.package1; 

public interface ICamera { 
    void snap(); 
} 

HTH。

1

當您設置proxy-target-class = false時,CGLIB代理仍然使用相同的公式JDK代理創建。 在Spring文檔中,他們說:

Spring AOP使用JDK動態代理或CGLIB爲給定目標對象創建代理。 (只要有選擇,JDK動態代理就是首選)。

如果要代理的目標對象實現至少一個接口,則將使用JDK動態代理。所有由目標類型實現的接口都將被代理。如果目標對象沒有實現任何接口,則將創建一個CGLIB代理。

查看更多:Proxying mechanisms

+0

瞭解該代理將被創建。問題仍然是爲什麼Spring 4不會拋出代理問題? – spock