Java 在Spring4中,代理问题是否得到了妥善处理?

Java 在Spring4中,代理问题是否得到了妥善处理?,java,spring,Java,Spring,我找不到任何文件来回答这个问题 总结如下: 我有一个实现接口的bean 我将代理目标类设置为false 我在Spring 3.2.17和4.3.3版本之间切换 当我使用Spring 3.2.17时,主类抛出以下命令: java.lang.ClassCastException:com.sun.proxy.$Proxy7不能强制转换为 com.package1.Camera 位于com.package1.App.main(App.java:8) 这是我所期望的。这是正确的行为,因为JDK代理类是生

我找不到任何文件来回答这个问题

总结如下:

  • 我有一个实现接口的bean
  • 我将代理目标类设置为false
  • 我在Spring 3.2.17和4.3.3版本之间切换
  • 当我使用Spring 3.2.17时,主类抛出以下命令:

    java.lang.ClassCastException:com.sun.proxy.$Proxy7不能强制转换为 com.package1.Camera 位于com.package1.App.main(App.java:8)

    这是我所期望的。这是正确的行为,因为JDK代理类是生成的

  • 但是当我使用Spring4.3.3时,不会抛出异常,并且主类可以正常运行

    生成了CGLIB代理类。但是,当我将代理目标类设置为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();
    }
}
package com.package1;
public interface ICamera {}
package com.package1;

import org.springframework.stereotype.Component;

@Component("camera")
public class Camera implements ICamera {
    public void snap() {
        System.out.println("SNAP!");
    }
}
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...");
    }

}
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();
    }
}
package com.package1;
public interface ICamera {}
package com.package1;

public interface ICamera {
    void snap();
}
ICamera.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();
    }
}
package com.package1;
public interface ICamera {}
package com.package1;

import org.springframework.stereotype.Component;

@Component("camera")
public class Camera implements ICamera {
    public void snap() {
        System.out.println("SNAP!");
    }
}
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...");
    }

}
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();
    }
}
package com.package1;
public interface ICamera {}
package com.package1;

public interface ICamera {
    void snap();
}
Camera.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();
    }
}
package com.package1;
public interface ICamera {}
package com.package1;

import org.springframework.stereotype.Component;

@Component("camera")
public class Camera implements ICamera {
    public void snap() {
        System.out.println("SNAP!");
    }
}
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...");
    }

}
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();
    }
}
package com.package1;
public interface ICamera {}
package com.package1;

public interface ICamera {
    void snap();
}
Logger.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();
    }
}
package com.package1;
public interface ICamera {}
package com.package1;

import org.springframework.stereotype.Component;

@Component("camera")
public class Camera implements ICamera {
    public void snap() {
        System.out.println("SNAP!");
    }
}
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...");
    }

}
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();
    }
}
package com.package1;
public interface ICamera {}
package com.package1;

public interface ICamera {
    void snap();
}
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>
<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>

pom.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>
<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>

4.0.0
com.package1
spring测试应用程序
0.0.1-快照
org.springframework
弹簧芯
4.3.3.1发布
org.springframework
春豆
4.3.3.1发布
org.springframework
spring上下文支持
4.3.3.1发布
org.springframework
春季方面
4.3.3.1发布

当设置proxy target class=false时,CGLIB proxy仍然使用相同的公式JDK proxy创建。 在春季文档中,他们说:

SpringAOP使用JDK动态代理或CGLIB为给定的目标对象创建代理。(只要有选择,JDK动态代理是首选)

如果要代理的目标对象实现了至少一个接口,那么将使用JDK动态代理。目标类型实现的所有接口都将被代理。如果目标对象未实现任何接口,则将创建CGLIB代理


查看更多信息:

通过反复试验,我找到了答案

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();
    }
}
package com.package1;
public interface ICamera {}
package com.package1;

import org.springframework.stereotype.Component;

@Component("camera")
public class Camera implements ICamera {
    public void snap() {
        System.out.println("SNAP!");
    }
}
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...");
    }

}
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();
    }
}
package com.package1;
public interface ICamera {}
package com.package1;

public interface ICamera {
    void snap();
}
代理目标类仍然默认为false

但是现在,Spring4已经足够聪明了,它将生成什么样的代理(JDK或CGLIB)

  • 如果您有一个空接口,它将生成一个CGLIB代理
ICamera.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();
    }
}
package com.package1;
public interface ICamera {}
package com.package1;

import org.springframework.stereotype.Component;

@Component("camera")
public class Camera implements ICamera {
    public void snap() {
        System.out.println("SNAP!");
    }
}
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...");
    }

}
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();
    }
}
package com.package1;
public interface ICamera {}
package com.package1;

public interface ICamera {
    void snap();
}
  • 否则,将生成JDK代理
ICamera.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();
    }
}
package com.package1;
public interface ICamera {}
package com.package1;

import org.springframework.stereotype.Component;

@Component("camera")
public class Camera implements ICamera {
    public void snap() {
        System.out.println("SNAP!");
    }
}
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...");
    }

}
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();
    }
}
package com.package1;
public interface ICamera {}
package com.package1;

public interface ICamera {
    void snap();
}

HTH.

了解将创建代理。问题仍然是为什么Spring 4没有抛出代理问题?它甚至是一个代理吗。。。我看不到任何方面。。。没有匹配的方面,没有代理,没有错误…我不知道为什么,但此代码仍在工作。您可以在此处检查我的代码:@M.Deinum,我刚刚添加了方面类:Logger.javarepo中的代码没有方面。。。不会创建任何代理,因为没有可为其创建代理的内容。