Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 编织没有接口和非公共方法的类时理解SpringAOP的问题_Java_Spring_Aop_Spring Aop - Fatal编程技术网

Java 编织没有接口和非公共方法的类时理解SpringAOP的问题

Java 编织没有接口和非公共方法的类时理解SpringAOP的问题,java,spring,aop,spring-aop,Java,Spring,Aop,Spring Aop,我正在学习SpringAOP,为了理解它是如何工作的,我创建了一个简单的项目。请在下面找到我的项目的主要部分: myspring-Customer.xml <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schem

我正在学习SpringAOP,为了理解它是如何工作的,我创建了一个简单的项目。请在下面找到我的项目的主要部分:

myspring-Customer.xml

<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"
    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-3.0.xsd ">

    <aop:aspectj-autoproxy />



    <bean id="customerBoNoIterface" class="com.core.CustomerBoNoIterface" />


    <!-- Aspect -->
    <bean id="logAspect" class="com.aspect.LoggingAspect" />

</beans>
请在下面找到我的班级客户主页:

   public class CustomerBoNoIterface {

    private void addCustmerPrivate() {
        System.out.println("calling addCustmerPrivate()");
    }

    public void addCustmerPublic() {

        System.out.println("calling addCustmerPublic()");

    }

    protected void addCustmerProtected() {

        System.out.println("calling addCustmerProtected()");

    }

    void addCustmerDefault() {

        System.out.println("calling addCustmerDefault()");

    }



    public String addCustmerReturnString() {

        System.out.println("calling addCustmerPublic return string");
        return "";

    }

}
最后是我的主要方法:

public class App {
    public static void main(String[] args) throws Exception {

        ApplicationContext appContext = new ClassPathXmlApplicationContext("Spring-Customer.xml");

        CustomerBoNoIterface customerBoNoIterfaceBean =appContext.getBean("customerBoNoIterface", CustomerBoNoIterface.class);
        customerBoNoIterfaceBean.addCustmerPublic();
        customerBoNoIterfaceBean.addCustmerDefault();
        customerBoNoIterfaceBean.addCustmerProtected();
        customerBoNoIterfaceBean.addCustmerReturnString();



    }
根据在线参考,Spring AOP由代理完成,类需要实现一个接口,以便Spring能够编织方面,并且Spring将只编织方面到公共方法

然而,在我的例子中,我有一个没有接口的类,如上面的例子所示,我能够在以下方法中应用AOP:

            customerBoNoIterfaceBean.addCustmerPublic();
        customerBoNoIterfaceBean.addCustmerDefault();
        customerBoNoIterfaceBean.addCustmerProtected();
        customerBoNoIterfaceBean.addCustmerReturnString();
因此,当我在eclipse中运行Main方法时,我在控制台中获得以下输出:

hijacked : addCustmerPublic
******
calling addCustmerPublic()
hijacked : addCustmerDefault
******
calling addCustmerDefault()
hijacked : addCustmerProtected
******
calling addCustmerProtected()
hijacked : addCustmerReturnString
******
calling addCustmerPublic return string
所以我无法理解Spring如何能够在除public之外的方法中编织方面,以及如何在没有接口的类中编织方面


提前感谢,

摘自spring doku:

SpringAOP默认使用标准J2SE动态代理作为AOP代理。这允许代理任何接口(或接口集)

SpringAOP也可以使用CGLIB代理。这对于代理类而不是接口是必需的。如果业务对象未实现接口,则默认情况下使用CGLIB。由于编程到接口而不是类是一种很好的实践,所以业务类通常会实现一个或多个业务接口。在需要建议未在接口上声明的方法的情况下,或者需要将代理对象作为具体类型传递给方法的情况下,可以强制使用CGLIB

只要阅读Spring文档就可以了,这是非常棒的

总而言之:您不需要仅仅为了实现AOP而实现接口。如果不实现接口,则直接基于类生成CGLIB代理。事实上,我经常用它。您确实需要在类路径上使用cglib,因为:

编辑
更多关于我个人偏好的信息(很多人可能不同意)。最近,我不再为任何东西编写接口。现在,我只在真正必要的时候使用它们(例如,我有两个实现,比如用于测试),这确实加快了我的工作,简化了我的代码。使用带有文本替换等功能的现代IDE,如果您真的需要接口,那么在以后提取接口并不难(对我来说非常罕见)。这只是我个人的观点。

摘自spring doku:

SpringAOP默认使用标准J2SE动态代理作为AOP代理。这允许代理任何接口(或接口集)

SpringAOP也可以使用CGLIB代理。这对于代理类而不是接口是必需的。如果业务对象未实现接口,则默认情况下使用CGLIB。由于编程到接口而不是类是一种很好的实践,所以业务类通常会实现一个或多个业务接口。在需要建议未在接口上声明的方法的情况下,或者需要将代理对象作为具体类型传递给方法的情况下,可以强制使用CGLIB

只要阅读Spring文档就可以了,这是非常棒的

总而言之:您不需要仅仅为了实现AOP而实现接口。如果不实现接口,则直接基于类生成CGLIB代理。事实上,我经常用它。您确实需要在类路径上使用cglib,因为:

编辑
更多关于我个人偏好的信息(很多人可能不同意)。最近,我不再为任何东西编写接口。现在,我只在真正必要的时候使用它们(例如,我有两个实现,比如用于测试),这确实加快了我的工作,简化了我的代码。使用带有文本替换等功能的现代IDE,如果您真的需要接口,那么在以后提取接口并不难(对我来说非常罕见)。这只是我个人的看法。

当使用这些方法时,Spring AOP使用反射API处理每个带注释的类,不会直接调用类的方法。因此,建议方法的可见性在这里并不重要

SpringAOP提供了两种代理 1) JDK代理:如果您的类实现了至少一个接口,那么这个代理就会出现

2) CGLIB代理:当你的类没有实现任何接口时,这个代理就会出现


在您的情况下,您的类没有实现任何接口,因此您的类将使用CGLIB代理进行代理

当使用方法时,Spring AOP使用反射API处理每个带注释的类,不会直接调用类的方法。因此,建议方法的可见性在这里并不重要

SpringAOP提供了两种代理 1) JDK代理:如果您的类实现了至少一个接口,那么这个代理就会出现

2) CGLIB代理:当你的类没有实现任何接口时,这个代理就会出现


在您的情况下,您的类没有实现任何接口,因此您的类将使用CGLIB代理进行代理

谢谢你的回答现在有意义谢谢你的回答现在有意义谢谢你的回答现在有意义如果它解决了你的问题,你应该接受答案。谢谢你的回答现在有意义如果它解决了你的问题,你应该接受答案。
hijacked : addCustmerPublic
******
calling addCustmerPublic()
hijacked : addCustmerDefault
******
calling addCustmerDefault()
hijacked : addCustmerProtected
******
calling addCustmerProtected()
hijacked : addCustmerReturnString
******
calling addCustmerPublic return string