3

I have been writing an aspect that manipulates some of my JPA entities getters. It is supposed to re-format the returned text based on the clients locale. Because not all of my getters should be reformatted I introduced an annotation @ReFormat.

The problem is my aspect is never intercepted when I advise it to an JPA entity but it works fine on non JPA entities (it works when I create my own entity object via a copy constructor).

My annotation:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface ReFormat {

}

My aspect:

@Aspect
public class ReFormatAspect {
    @AfterReturning(pointcut = "@annotation(com.path.ReFormat)", returning = "response")
    public Object formatter(JoinPoint joinPoint, Object response) {
       return response;
    }
}

Now this aspect is intercepted successfully within my MVC controllers (or at any other place except spring data) but not for my entities.

@Entity
@Table(name = "place", schema = "db")
public class TestEntity {

   @Id
   @Column(name = "id")
   protected long id;

   @Column(name = "about", columnDefinition = "TEXT DEFAULT NULL")
   protected String about;

   @ReFormat
   public String getAbout() {
       return this.about;
   }

}

I expected a point cut once the getAbout method is called, but it does not work.

Given the facts above I suppose that JPA (Hibernate) is overriding any interceptor may be by CGLib or javassist.

Note: I have this inside my context

<context:annotation-config />
<context:spring-configured />
<aop:aspectj-autoproxy proxy-target-class="true" />

So what is the exact issue, and how do I intercept any method inside an entity?

I understand this should be the view layer work, but still I need to know why :D

4

3 回答 3

3

您的实体不由 Spring 管理,它们由底层 JPA 实现管理。因此,Spring 无法将它们包装在代理中并提供所需的行为。

没有 Spring 方法可以解决这个问题。Hibernate 可能有一些拦截器工具(在创建实体时包装它们),但我不知道。也许扩展EmptyInterceptor

于 2013-08-30T14:12:36.570 回答
2

您始终可以使用 AspectJ 并在编译时挥动您的方面。但是这样你将无法访问 spring DI 容器。

于 2013-08-30T14:20:47.350 回答
1

可以将 AspectJ 方面与 Spring DI 容器一起使用。Spring AOP文档说:

域对象通常属于这一类,因为它们通常是使用 new 运算符以编程方式创建的,或者由 ORM 工具作为数据库查询的结果创建。

我创建了一个GitHub 项目,在该项目中我@ReFormat在一个用@Entity. 为了能够在您的 AspectJ 方面使用 DI,您需要使用aspectOf()方法。这甚至可以通过JavaConfig实现。因此,您根本不必使用 XML 配置。

于 2014-10-29T20:41:55.297 回答