2015-04-02 48 views
0

Java + Spring + Maven應用程序。
無法通過基於註解的公共方法進行內部調用。Spring AOP + AspectJ maven插件 - 內部方法調用不起作用

前提

  1. Java的版本:1.7。
  2. 項目:AspectProject>發佈構建它將創建jar文件。
  3. 客戶端:AspectClient:它依賴於「AspectProject」。

AspectProject

  1. 的pom.xml
<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> 
  • AspectProvider
  • @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; 
        } 
    } 
    
  • 註釋 「TestAnnotation」
  • @Component 
    @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE}) 
    @Retention(RetentionPolicy.RUNTIME) 
    public @interface TestAnnotation { 
        String value(); 
    } 
    

    AspectClient

    1. 的pom.xml
    <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> 
    
  • 服務等級
  • @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; 
        } 
    
    } 
    
  • 彈簧的context.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: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> 
    
  • Main類
  • 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** 
    

    的情況下,請諮詢我是否錯過任何進入或更改configuration.Thanks提前爲您寶貴的時間要求。

    回答

    1

    你所做的有點奇怪,因爲一方面你配置Spring使用(自動)基於代理的Spring AOP,另一方面你使用AspectJ Maven插件來使用本地AspectJ並進行編譯時編織。請確定你想要哪個方向走:

    • 查看Spring AOP不需要AspectJ編譯器,但隨後你被卡住它自帶的內部通話的費用不是基於代理的「AOP精簡版」的方法被方面攔截,因爲它們不通過代理,而是通過this(原始對象)。
    • 對於成熟的AspectJ,您可以將Spring配置爲使用LTW(加載時織入),如手冊章節Using AspectJ with Spring applications中所述。或者,您也可以使用編譯時編織,但除非在應用程序啓動過程中遇到性能問題,否則這不是必需的。
    +0

    謝謝Kriegaex。我是aop概念的新手。你是對的,我錯誤地搞亂了Spring-aop和AspectJ編譯器。我想要AspectJ功能,以便內部呼叫被方面攔截。 – JavaDev 2015-04-07 21:33:06