Spring AOP + AspectJ maven插件 - 内部方法调用不起作用

时间:2015-04-02 00:07:30

标签: java maven aspectj spring-aop aspectj-maven-plugin

Java + Spring + Maven应用程序。
无法从基于注释的公共方法进行内部调用。

前提条件

  1. Java版本:1.7。
  2. 项目: AspectProject >构建后它将创建jar文件。
  3. 客户端: AspectClient :具有“AspectProject”的依赖关系。
  4. AspectProject

    1. 的pom.xml
    2. <properties>
              <java.version>1.7</java.version>    
              <maven.compiler.source>1.7</maven.compiler.source>
              <maven.compiler.target>1.7</maven.compiler.target>
              <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
              <springframework.version>4.1.2.RELEASE</springframework.version>        
              <org.aspectj-version>1.7.0</org.aspectj-version>
        </properties>
      
        <dependencies>
      
          <!-- Spring --> 
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-web</artifactId>
              <version>${springframework.version}</version>
          </dependency>
      
           <!-- AspectJ dependencies -->
          <dependency>
              <groupId>org.aspectj</groupId>
              <artifactId>aspectjrt</artifactId>
              <version>${org.aspectj-version}</version>
              <scope>runtime</scope>
          </dependency>
          <dependency>
              <groupId>org.aspectj</groupId>
              <artifactId>aspectjtools</artifactId>
              <version>${org.aspectj-version}</version>
          </dependency>
      
        </dependencies>
      
         <build> 
          <sourceDirectory>src/main/java</sourceDirectory>
          <plugins>   
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-compiler-plugin</artifactId>
                  <version>3.1</version>
                      <!-- compile for Java 1.7 -->
                      <configuration>
                          <source>${maven.compiler.source}</source>
                          <target>${maven.compiler.target}</target>
                          <encoding>${project.build.sourceEncoding}</encoding>
                      </configuration>
              </plugin>
              <plugin>
                      <groupId>org.codehaus.mojo</groupId>
                      <artifactId>aspectj-maven-plugin</artifactId>
                      <version>1.4</version>
                      <dependencies>
                          <dependency>
                              <groupId>org.aspectj</groupId>
                              <artifactId>aspectjrt</artifactId>
                              <version>${org.aspectj-version}</version>
                          </dependency>
                          <dependency>
                              <groupId>org.aspectj</groupId>
                              <artifactId>aspectjtools</artifactId>
                              <version>${org.aspectj-version}</version>
                          </dependency>
                      </dependencies>
                      <executions>
                          <execution>
                              <phase>process-sources</phase>
                              <goals>
                                  <goal>compile</goal>
                                  <goal>test-compile</goal>
                              </goals>
                              <configuration>
                                  <complianceLevel>${maven.compiler.source}</complianceLevel>
                                  <source>${maven.compiler.source}</source>
                                  <target>${maven.compiler.target}</target>
                              </configuration>
                          </execution>
                      </executions>
              </plugin>
          </plugins>
        </build>
      
      1. AspectProvider
      2. @Aspect
        public class AspectProvider {   
            /**
             * This is the point cut for all get Method with @TestAnnotation annotation
             */
            @Pointcut("execution(* get*()) && @annotation(aTestAnnotation)")
            public void getMethodPointcut(TestAnnotation aTestAnnotation) {}
        
        
            @Around("getMethodPointcut(aTestAnnotation)")
            public Object getConfiguration(ProceedingJoinPoint iJoinPoint, TestAnnotation aTestAnnotation) throws Throwable {
                return getValueFromISTCompositeConfiguration(iJoinPoint, aTestAnnotation);
            }
        
            private Object getValueFromISTCompositeConfiguration(final ProceedingJoinPoint iProceedingJoinPoint, TestAnnotation aTestAnnotation) throws Throwable {
        
                Object aReturnValue = null;
                if (aTestAnnotation.value() != null) {
                    System.out.println("ASPECT: Returning annotation value.");
                    aReturnValue = aTestAnnotation.value();
                } else {
                    System.out.println("MISSING_GETTER_PROPERTY");
                }    
                if(aReturnValue == null){
                     aReturnValue = iProceedingJoinPoint.proceed();
                }
                return aReturnValue;
            }
        }
        
        1. 注释“TestAnnotation”
        2. @Component
          @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
          @Retention(RetentionPolicy.RUNTIME)
          public @interface TestAnnotation {  
              String value();
          }
          

          AspectClient

          1. 的pom.xml
          2. <properties>
                    <java.version>1.7</java.version>
                    <maven.compiler.source>1.7</maven.compiler.source>
                    <maven.compiler.target>1.7</maven.compiler.target>
                    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
                    <aspectProject.version>0.0.1-SNAPSHOT</aspectProject.version>
                    <spring-framework.version>4.1.2.RELEASE</spring-framework.version>
                    <org.aspectj-version>1.7.0</org.aspectj-version>
                </properties>
            
                <dependencies>
                    <!-- Spring -->
                    <dependency>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-context</artifactId>
                        <version>${spring-framework.version}</version>
                    </dependency>
            
                    <!-- AspectProject dependencies -->
                    <dependency>
                        <groupId>com.example.aop</groupId>
                        <artifactId>AspectProject</artifactId>
                        <version>${aspectProject.version}</version>
                    </dependency>
                </dependencies>
            
            <build>
              <sourceDirectory>src/main/java/</sourceDirectory>
              <plugins>
                        <plugin>
                            <groupId>org.apache.maven.plugins</groupId>
                            <artifactId>maven-compiler-plugin</artifactId>
                            <version>3.1</version>
                            <!-- compile for Java 1.7 -->
                            <configuration>
                                <source>${maven.compiler.source}</source>
                                <target>${maven.compiler.target}</target>
                                <encoding>${project.build.sourceEncoding}</encoding>
                            </configuration>
                       </plugin>
            
                        <plugin>
                            <groupId>org.codehaus.mojo</groupId>
                            <artifactId>aspectj-maven-plugin</artifactId>
                            <version>1.4</version>
                            <configuration>
                                <showWeaveInfo>true</showWeaveInfo>
                                <aspectLibraries>
                                    <aspectLibrary>
                                         <groupId>com.example.aop</groupId>
                                         <artifactId>AspectProject</artifactId>
                                    </aspectLibrary>
                                </aspectLibraries>
                                <complianceLevel>${maven.compiler.source}</complianceLevel>
                                <source>${maven.compiler.source}</source>
                                <target>${maven.compiler.target}</target>
                            </configuration>
                            <executions>
                                <execution>
                                    <phase>process-sources</phase>
                                    <goals>
                                        <goal>compile</goal> 
                                        <goal>test-compile</goal>
                                    </goals>
                                </execution>
                            </executions>
                            <dependencies>
                                <dependency>
                                    <groupId>org.aspectj</groupId>
                                    <artifactId>aspectjrt</artifactId>
                                    <version>${org.aspectj-version}</version>
                                </dependency>
                                <dependency>
                                    <groupId>org.aspectj</groupId>
                                    <artifactId>aspectjtools</artifactId>
                                    <version>${org.aspectj-version}</version>
                                </dependency>
                            </dependencies>
                        </plugin> 
              </plugins>    
            </build>
            
            1. 服务类
            2. @Component
              public class TestService {
              
                  private String value;
              
                  public void internalCall() {
                      System.out.println("INTERNAL_CALL :"+ getValue());
                  }
              
                  @TestAnnotation("RETURNED_FROM_ASPECT_CALL") 
                  public String getValue() {
                      return value;
                  }
              
                  public void setValue(String iValue) {
                      this.value = iValue;
                  }
              
              }
              
              1. Spring context.xml
              2. <?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:context="http://www.springframework.org/schema/context"
                    xmlns:aop="http://www.springframework.org/schema/aop"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
                
                    <!-- Enable AspectJ style of Spring AOP -->
                    <context:component-scan base-package="com.example.aop.client" />
                
                    <aop:aspectj-autoproxy />
                
                    <bean name="TestService" class="com.example.aop.client.service.TestService" />
                
                    <!-- Configure Aspect Beans, without this Aspects advice wont execute -->
                    <bean name="aspectProvider" class="com.example.aop.aspect.AspectProvider"/> 
                
                </beans>
                
                1. 主要课程
                2. public class SpringMain {
                  
                      public static void main(String[] args) {
                          ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
                          TestService aTestService = ctx.getBean("TestService", TestService.class);
                  
                          System.out.println("EXTERNAL_CALL: "+aTestService.getValue());
                          aTestService.internalCall();        
                          ctx.close();
                      }
                  
                  }
                  

                  输出:

                  ASPECT: Returning annotation value. 
                  EXTERNAL_CALL:RETURNED_FROM_ASPECT_CALL 
                  INTERNAL_CALL: **null**
                  

                  预期:

                  ASPECT: Returning annotation value.
                  EXTERNAL_CALL: RETURNED_FROM_ASPECT_CALL
                  INTERNAL_CALL: **RETURNED_FROM_ASPECT_CALL**
                  

                  如果我遗漏任何条目或需要更改配置,请提供建议。请提前感谢您的宝贵时间。

1 个答案:

答案 0 :(得分:1)

你做的有点奇怪,因为一方面你将Spring配置为使用(自动)基于代理的Spring AOP,另一方面你使用AspectJ Maven插件来使用原生AspectJ并进行编译时编织。请确定您想要的方式:

  • 对于Spring AOP,你不需要AspectJ编译器,但是你会遇到基于代理的&#34; AOP lite&#34;这种方法的代价是内部调用没有被方面截获,因为它们不通过代理而是通过this(原始对象)。
  • 对于成熟的AspectJ,您可以将Spring配置为使用LTW(加载时编织),如手册章Using AspectJ with Spring applications中所述。或者,您也可以使用编译时编织,但除非在应用程序启动期间出现性能问题,否则不需要这样做。