如何使用AOP和Spring Boot启用hibernate过滤器?

时间:2017-03-17 20:25:06

标签: hibernate spring-boot spring-aop

我正在尝试使用Spring AOP和Spring Boot启用一个hibernate过滤器。我使用这篇文章作为起点:How to enable hibernate filter for sessionFactory.getCurrentSession()?

到目前为止,我还无法拦截Hibernate会话:org.hibernate.internal.SessionFactoryImpl.SessionBuilderImpl.openSession()。

我的方面类看起来像这样:

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import com.acme.CustomUserDetails;

@Component
@Aspect
public class ACLFilter {
    Logger log = LoggerFactory.getLogger(ACLFilter.class);

    @AfterReturning(pointcut = "execution(* org.hibernate.internal.SessionFactoryImpl.openSession(..)))", returning = "session")
    public void forceFilter(JoinPoint joinPoint, Object session) {
        Session hibernateSession = (Session) session;
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        Long userId = ((CustomUserDetails) auth.getDetails()).getUserId();
        // Session session = em.unwrap(Session.class);
        hibernateSession.enableFilter("groupACL").setParameter("userId", userId);
    }

    @Before("execution(* org.hibernate.SessionFactory.openSession(..)))")
    public void do2(JoinPoint joinPoint) {
        System.out.println("############################do2");
    }

    @Before("execution(* org.hibernate.SessionBuilder.openSession(..)))")
    public void do3(JoinPoint joinPoint) {
        System.out.println("############################do3");
    }

    @Before("execution(* org.hibernate.internal.SessionFactoryImpl.SessionBuilderImpl.openSession(..)))")
    public void do4(JoinPoint joinPoint) {
        System.out.println("############################do4");
    }

}

这是我试图拦截的所有类/方法。我还验证了方面类与测试类/方法一起工作正常,因此AOP设置是正确的。 在调试时我可以看到系统触发org.hibernate.internal.SessionFactoryImpl.SessionBuilderImpl.openSession() 但是不会触发我的拦截器? 我的application.properties文件包含以下条目:

spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext

我错过了什么?

1 个答案:

答案 0 :(得分:2)

Hibernate类不是Spring组件,因此Spring AOP不适用于它们。如果你想截取它们,我建议你切换到完整的AspectJ with load-time weaving。然后你也可以选择不使用execution()来操作Hibernate的字节码,而call()只会改变你自己的类。