Spring AOP和Spring JPA,要执行的Aspect

时间:2013-08-30 13:21:39

标签: java spring aspectj spring-data spring-aop

我一直在编写一个操纵我的一些JPA实体getter的方面。它应该根据客户端区域设置重新格式化返回的文本。因为不是所有的getter都应该重新格式化,所以我引入了一个注释@ReFormat

问题是当我向JPA实体提出建议时,我的方面从未被截获,但它在非JPA实体上工作正常(当我通过复制构造函数创建自己的实体对象时,它可以正常工作)。

我的注释:

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

}

我的方面:

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

现在这个方面在我的MVC控制器(或除了弹簧数据之外的任何其他地方)成功拦截,但不是我的实体。

@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;
   }

}

一旦调用getAbout方法,我预计会有一个切点,但它不起作用。

鉴于上述事实,我认为JPA(Hibernate)覆盖任何拦截器可能是CGLib或javassist。

注意:我在我的上下文中有这个

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

那么究竟是什么问题,我如何拦截实体内的任何方法?

我明白这应该是视图层工作,但我仍然需要知道原因:D

3 个答案:

答案 0 :(得分:2)

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

没有Spring解决方法。 Hibernate可能有一些拦截器工具(它们在创建时包装实体)但我不知道。也许会延长EmptyInterceptor

答案 1 :(得分:1)

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

  

域对象通常属于此类别,因为它们通常使用new运算符以编程方式创建,或者由于数据库查询而由ORM工具创建。

我创建了一个GitHub project,我在@ReFormat注释的bean的方法上使用@Entity注释。为了能够在AspectJ方面使用DI,您需要使用aspectOf() approachJavaConfig甚至可以实现这一点。因此,您根本不必使用XML配置。

答案 2 :(得分:0)

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

相关问题