为什么构造函数只在Spring AOP中执行一次

时间:2015-01-26 07:39:05

标签: java spring spring-aop

我试图理解春天。我读了spring doc。它表示方面的构造函数运行两次,一次用于原始类对象,另一次用于代理对象。但是当我尝试使用公共构造函数创建自己的方面时,它只执行一次。

以下是我的代码段:

package com.akash.aop;

public class TestAopBefore {

    public TestAopBefore() {
        System.out.println("TestAopBefore.TestAopBefore()");
    }

    private String name;

    public String getName() {
        System.out.println("TestAopBefore.getName()");
        return name;
    }

    public void setName(String name) {
        System.out.println("TestAopBefore.setName()");
        this.name = name;
    }
}

我的Aspect类

package com.akash.aop;

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

@Aspect
public class MyAspect {

    @Before("execution(* com.akash.aop.TestAopBefore.get*())")
    public void runBeforeAllGetter() {
        System.out.println("MyAspect.runBeforeAllGetter()");
    }
}

我的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.xsd">


    <bean id="testAopBefore" class="com.akash.aop.TestAopBefore" />
    <bean id="myAspect" class="com.akash.aop.MyAspect" />

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

</beans>

我的应用课程

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

public class App {

    public static void main(String[] args) {

        AbstractApplicationContext context = new ClassPathXmlApplicationContext(
                "myAop.xml");
        TestAopBefore testAopBefore = (TestAopBefore) context
                .getBean("testAopBefore");
        testAopBefore.setName("asd");
        testAopBefore.getName();
    }
}

这是输出:

TestAopBefore.TestAopBefore()
TestAopBefore.setName()
MyAspect.runBeforeAllGetter()
TestAopBefore.getName()

编辑:

我正在使用maven项目,这是我的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>SpringDemo</groupId>
    <artifactId>SpringDemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties>
        <org.springframework-version>4.0.3.RELEASE</org.springframework-version>
        <org.aspectj-version>1.6.10</org.aspectj-version>
    </properties>

    <build>
        <sourceDirectory>src</sourceDirectory>
        <resources>
            <resource>
                <directory>resource</directory>
                <excludes>
                    <exclude>**/*.java</exclude>
                </excludes>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>

        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework-version}</version>
            <exclusions>
                <!-- Exclude Commons Logging in favor of SLF4j -->
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>

        <!-- AspectJ -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${org.aspectj-version}</version>
        </dependency>
         <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>${org.aspectj-version}</version>
        </dependency> 
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2.2</version>
        </dependency> 

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${org.springframework-version}</version>
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.5.8</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.5.8</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.5.8</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        <version>1.2.14</version>

    </dependency>

    </dependencies>

</project>

我还为cglib添加了依赖项,但我认为我的代码没有使用它。

1 个答案:

答案 0 :(得分:5)

我不太确定为什么你需要两次调用你的构造函数,但如果你需要解释,那就是。

从Spring 4.0开始DefaultAopProxyFactory使用ObjenesisCglibAopProxy创建代理实例,而不调用类上的默认构造函数。因此,如果您需要双构造函数行为,则应降级到Spring 3.x或创建自己的AopProxyFactory实现。

干杯