2014-10-20 226 views
1

我以前沒有使用AOP之前在春天,所以我「米只是試圖讓一個簡單的例子,我的申請工作如何配置AOP在Spring

這是我使用的代碼:

/** 
* The product cache aspect manages the product cache. 
* 
*/ 
@Aspect 
public class ProductCacheAspect { 

    private static Logger logger = LogManager.getLogger(ProductCacheAspect.class.getName()); 

    @Autowired 
    private MemcachedClient memcachedClient; 

    @AfterReturning(
      pointcut = "execution(* com.ideafactory.mvc.products.common.services.ProductService.get(..))", 
      returning= "result") 
    public void logAfterReturning(JoinPoint joinPoint, Object result) { 
     logger.debug("Executed point cut"); 
     logger.debug(result); 
    } 
} 

而且我覺得我有它正確配置:

@Configuration 
@ComponentScan(basePackages = {"com.ideafactory"}) 
@PropertySource(value = {"classpath:application.properties"}) 
@EnableScheduling 
**@EnableAspectJAutoProxy** 
@EnableCaching 
@EnableTransactionManagement 
public class AppConfig { 
... 
} 

我也有pom.xml中設置了進口的AspectJ

但是當我嘗試在ProductService上執行get方法時,它不會輸入方面方法。我不知道現在如何排除故障。

任何人都可以提出什麼可能是錯的?

==========被建議的方法=============

@Override 
    @Transactional(readOnly = true, rollbackFor = Exception.class) 
    public Product get(long productId) { 
     logger.entry(); 


     Product product = null; 


     // check the cache first, if it's in cache we'll use that. 
     product = (Product) memcachedClient.get(Product.getCacheKey(productId)); 


     if (product == null) 
     { 
      product = productRepository.findOne(productId); 
      // now we initialise the product. 
      if (product != null) { 
       Hibernate.initialize(product.getImageSets()); 
       Hibernate.initialize(product.getTags()); 
       Hibernate.initialize(product.getVariantOptions()); 
       Hibernate.initialize(product.getVariants()); 
       Hibernate.initialize(product.getChildRelationships()); 
       memcachedClient.set(Product.getCacheKey(productId), 3600, product); 
      } 
     } 

     logger.exit(); 
     return product; 

    } 

===========類定義=============

package com.ideafactory.mvc.products.common.services; 
@Service 
public class ProductServiceImpl implements ProductService 
{ 
... 
} 

============添加的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>com.ideafactory</groupId> 
    <artifactId>java_ecommerce</artifactId> 
    <version>1.0</version> 
    <packaging>war</packaging> 


    <properties> 
     <java.version>1.7</java.version> 
     <junit.version>4.11</junit.version> 
     <log4j.version>2.0-rc2</log4j.version> 
     <spring.version>4.0.6.RELEASE</spring.version> 
     <spring-data-jpa.version>1.7.0.RELEASE</spring-data-jpa.version> 
     <spring-security.version>3.2.0.RELEASE</spring-security.version> 
     <hibernate.version>4.3.6.Final</hibernate.version> 
     <aspectj.version>1.8.2</aspectj.version> 
     <mysql.version>5.1.26</mysql.version> 
     <jackson-json.version>2.3.1</jackson-json.version> 
     <jackson-mapper-asl.version>1.9.13</jackson-mapper-asl.version> 
     <commons-dbcp.version>1.4</commons-dbcp.version> 
     <commons-lang3.version>3.1</commons-lang3.version> 
     <commons-io.version>2.4</commons-io.version> 
     <commons-upload.version>1.3.1</commons-upload.version> 
     <jmagick.version>6.6.9</jmagick.version> 
     <jadira.core.version>3.2.0.GA</jadira.core.version> 
     <joda-money-version>0.9.1</joda-money-version> 

     <!-- Cache --> 
     <spy-memcache-verion>2.11.4</spy-memcache-verion> 
    </properties> 

    <build> 
     <finalName>${project.artifactId}</finalName> 
     <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-compiler-plugin</artifactId> 
       <version>3.1</version> 
       <configuration> 
        <source>${java.version}</source> 
        <target>${java.version}</target> 
       </configuration> 
      </plugin> 
     </plugins> 
     <resources> 
      <resource> 
       <directory>src/main/resources</directory> 
      </resource> 
     </resources> 
    </build> 

    <dependencies> 
     <!-- Logging dependencies --> 

     <dependency> 
      <groupId>org.apache.logging.log4j</groupId> 
      <artifactId>log4j-core</artifactId> 
      <version>${log4j.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>org.apache.logging.log4j</groupId> 
      <artifactId>log4j-api</artifactId> 
      <version>${log4j.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>org.apache.logging.log4j</groupId> 
      <artifactId>log4j-jcl</artifactId> 
      <version>${log4j.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>org.apache.logging.log4j</groupId> 
      <artifactId>log4j-slf4j-impl</artifactId> 
      <version>2.0</version> 
     </dependency> 

     <!-- Spring dependencies --> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-context-support</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-webmvc</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-test</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-context</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 
     <!-- Spring Data JPA dependencies --> 

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

     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-entitymanager</artifactId> 
      <version>${hibernate.version}</version> 
     </dependency> 

     <!-- SpringSecurity dependencies --> 
     <dependency> 
      <groupId>org.springframework.security</groupId> 
      <artifactId>spring-security-core</artifactId> 
      <version>${spring-security.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.security</groupId> 
      <artifactId>spring-security-web</artifactId> 
      <version>${spring-security.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.security</groupId> 
      <artifactId>spring-security-config</artifactId> 
      <version>${spring-security.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.security</groupId> 
      <artifactId>spring-security-taglibs</artifactId> 
      <version>${spring-security.version}</version> 
     </dependency> 

     <!-- Dependencies required for AOP Programming --> 
     <dependency> 
      <groupId>org.aspectj</groupId> 
      <artifactId>aspectjweaver</artifactId> 
      <version>${aspectj.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.aspectj</groupId> 
      <artifactId>aspectjrt</artifactId> 
      <version>${aspectj.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>org.aspectj</groupId> 
      <artifactId>aspectjtools</artifactId> 
      <version>${aspectj.version}</version> 
     </dependency> 


     <!-- Testing dependencies --> 
     <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>${junit.version}</version> 
      <scope>test</scope> 
     </dependency> 

     <!-- DB dependencies --> 
     <dependency> 
      <groupId>mysql</groupId> 
      <artifactId>mysql-connector-java</artifactId> 
      <version>${mysql.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>commons-dbcp</groupId> 
      <artifactId>commons-dbcp</artifactId> 
      <version>${commons-dbcp.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>com.fasterxml.jackson.core</groupId> 
      <artifactId>jackson-databind</artifactId> 
      <version>${jackson-json.version}</version> 
     </dependency> 

     <!-- Jackson JSON Mapper --> 
     <dependency> 
      <groupId>org.codehaus.jackson</groupId> 
      <artifactId>jackson-mapper-asl</artifactId> 
      <version>${jackson-mapper-asl.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>javax.mail</groupId> 
      <artifactId>mail</artifactId> 
      <version>1.4.3</version> 
     </dependency> 

     <!-- Web dependencies --> 
     <dependency> 
      <groupId>javax.servlet</groupId> 
      <artifactId>javax.servlet-api</artifactId> 
      <version>3.0.1</version> 
      <scope>compile</scope> 
     </dependency> 


     <dependency> 
      <groupId>javax.servlet</groupId> 
      <artifactId>jstl</artifactId> 
      <version>1.2</version> 

     </dependency> 

     <dependency> 
      <groupId>javax.servlet.jsp</groupId> 
      <artifactId>jsp-api</artifactId> 
      <version>2.1</version> 
      <scope>provided</scope> 
     </dependency> 

     <dependency> 
      <groupId>org.glassfish.web</groupId> 
      <artifactId>jstl-impl</artifactId> 
      <version>1.2</version> 
      <exclusions> 
       <exclusion> 
        <artifactId>servlet-api</artifactId> 
        <groupId>javax.servlet</groupId> 
       </exclusion> 
       <exclusion> 
        <artifactId>jsp-api</artifactId> 
        <groupId>javax.servlet.jsp</groupId> 
       </exclusion> 
       <exclusion> 
        <artifactId>jstl-api</artifactId> 
        <groupId>javax.servlet.jsp.jstl</groupId> 
       </exclusion> 
      </exclusions> 
     </dependency> 

     <dependency> 
      <groupId>org.apache.tiles</groupId> 
      <artifactId>tiles-extras</artifactId> 
      <version>3.0.3</version> 
     </dependency> 

     <!-- Velocity for email templates --> 
     <dependency> 
      <groupId>org.apache.velocity</groupId> 
      <artifactId>velocity</artifactId> 
      <version>1.7</version> 
     </dependency> 
     <dependency> 
      <groupId>org.apache.velocity</groupId> 
      <artifactId>velocity-tools</artifactId> 
      <version>2.0</version> 
     </dependency> 



     <!-- Validations --> 
     <dependency> 
      <groupId>javax.validation</groupId> 
      <artifactId>validation-api</artifactId> 
      <version>1.1.0.Final</version> 
     </dependency> 
     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-validator</artifactId> 
      <version>5.1.1.Final</version> 
     </dependency> 
     <dependency> 
      <groupId>commons-validator</groupId> 
      <artifactId>commons-validator</artifactId> 
      <version>1.4.0</version> 
     </dependency> 


     <!-- dependency on SOLR data --> 
     <dependency> 
      <groupId>org.springframework.data</groupId> 
      <artifactId>spring-data-solr</artifactId> 
      <version>1.2.1.RELEASE</version> 
     </dependency> 

     <dependency> 
      <groupId>org.apache.solr</groupId> 
      <artifactId>solr-solrj</artifactId> 
      <version>4.9.0</version> 
     </dependency> 

     <dependency> 
      <groupId>org.apache.solr</groupId> 
      <artifactId>solr-core</artifactId> 
      <version>4.9.0</version> 
     </dependency> 

     <!-- This is for spring JPA framework auditing --> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-aspects</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-aop</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>joda-time</groupId> 
      <artifactId>joda-time-hibernate</artifactId> 
      <version>1.3</version> 
     </dependency> 

     <dependency> 
      <groupId>org.joda</groupId> 
      <artifactId>joda-money</artifactId> 
      <version>${joda-money-version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.jadira.usertype</groupId> 
      <artifactId>usertype.core</artifactId> 
      <version>${jadira.core.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>commons-fileupload</groupId> 
      <artifactId>commons-fileupload</artifactId> 
      <version>${commons-upload.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>commons-io</groupId> 
      <artifactId>commons-io</artifactId> 
      <version>${commons-io.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>org.im4java</groupId> 
      <artifactId>im4java</artifactId> 
      <version>1.4.0</version> 
     </dependency> 

     <!-- Cache Configuration --> 
     <dependency> 
      <groupId>net.spy</groupId> 
      <artifactId>spymemcached</artifactId> 
      <version>${spy-memcache-verion}</version> 
     </dependency> 

    </dependencies> 

    <dependencyManagement> 
     <dependencies> 
      <dependency> 
       <groupId>org.springframework</groupId> 
       <artifactId>spring-framework-bom</artifactId> 
       <version>${spring.version}</version> 
       <type>pom</type> 
       <scope>import</scope> 
      </dependency> 
     </dependencies> 
    </dependencyManagement> 

</project> 
+0

我最初誤以爲你試圖建議一個字段本身的切入點,但後來發現你正在嘗試在你的類中建議一個名爲get的方法。 你確實有一個叫get()的方法嗎?這似乎有點奇怪。你可以請張貼你試圖建議的類方法嗎? – 2014-10-21 02:19:28

+0

我剛更新了帖子。我使用get,因爲它很容易輸入:) – 2014-10-21 08:49:39

+0

你可以發佈Spring啓動日誌嗎? – 2014-10-21 15:07:18

回答

0

您的切入點試圖通知接口執行IIRC是不可能的(即:inte rface不是被執行的代碼)。你應該建議一個實現。此外,正如@Angad所建議的那樣,您可能還需要使用@Component對其進行註釋,以便Spring實際上自動掃描它(除非您有自定義自動檢測過濾器)。我不相信Spring會自動檢測/實例化@Aspect bean。

所以你有幾個選擇。

1:構建切入點實際建議的實施本身:

@AfterReturning(
     pointcut = "execution(* com.ideafactory.mvc.products.common.services.ProductServiceImpl.get(..))", 
     returning= "result") 
public void logAfterReturning(JoinPoint joinPoint, Object result) { 
    logger.debug("Executed point cut"); 
    logger.debug(result); 
} 

2:寫你的切入點,以告知接口和實現它的類(注意接口名稱末尾的+符號):

@AfterReturning(
     pointcut = "execution(* com.ideafactory.mvc.products.common.services.ProductService+.get(..))", 
     returning= "result") 
public void logAfterReturning(JoinPoint joinPoint, Object result) { 
    logger.debug("Executed point cut"); 
    logger.debug(result); 
} 
+0

謝謝埃裏克我已經添加了@Component,並且我嘗試了建議Impl類,但它仍然不會觸發。我剛剛發佈了POM.xml,我檢查了依賴關係,但也許我錯過了一些東西。 – 2014-10-21 14:53:13

+0

您是否看到Spring在啓動日誌中加載/實例化的bean bean?這可能是一個愚蠢的問題,但你確實有一些調用/執行'ProductServiceImpl.get()'方法的東西?當然,我認爲Aspect和ProductServiceImpl都是同一個項目的一部分?我會嘗試的下一步是讓你的切入點更加狂野。例如,將它設置爲執行(* *。*(..)),看看是否曾經觸發過。 – 2014-10-21 15:12:49

+0

肯定在同一個項目中,並且正在被調用。我將切入點設置爲泛型(* *。*(..)),它導致啓動失敗,因爲JPA審計框架中的某些類不支持aspect -J? '引發:java.lang.IllegalStateException:後處理器嘗試用[org.springframework.data.jpa類型的(代理)對象替換[org.springframework.data.jpa.domain.support.AuditingEntityListener]類型的bean實例.domain.support.AuditingEntityListener $$ EnhancerBySpringCGLIB $$ 9b405c2f] - 不支持方面配置的類!' – 2014-10-21 15:39:39

0

我看到你想用AOP來定義方法的緩存。如果是這樣,你可能想看看Simple Spring Memcached。它通過自定義註釋(@ReadThroughSingleCache, @UpdateMultiCache, @ReadThroughAssignCache, ...)或Spring Cache註釋(@Cacheable)在memcached中提供緩存。