如何使用 AOP 和 Spring 引导启用休眠过滤器?
How to enable hibernate filter using AOP and Spring Boot?
我正在尝试使用 Spring AOP 和 Spring Boot 启用休眠过滤器。我用这个 post 作为起点:How to enable hibernate filter for sessionFactory.getCurrentSession()?
到目前为止我还没能拦截 Hibernate session:org.hibernate.internal.SessionFactoryImpl.SessionBuilderImpl.openSession().
我的方面 class 是这样的:
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");
}
}
这就是我试图拦截的所有classes/methods。我还通过测试 class/method 验证了方面 class 是否正常工作并且确实如此,因此 AOP 设置是正确的。
在调试时我可以看到系统触发了 org.hibernate.internal.SessionFactoryImpl.SessionBuilderImpl.openSession()
但不会触发我的拦截器?
我的 application.properties 文件包含此条目:
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
我错过了什么?
Hibernate 类 不是 Spring 组件,因此 Spring AOP 不适用于它们。如果你想拦截他们,我建议你切换到完整的AspectJ with load-time weaving。然后你也可以选择不使用 execution()
来操纵 Hibernate 的字节码,而是 call()
只会改变你自己的 类.
我正在尝试使用 Spring AOP 和 Spring Boot 启用休眠过滤器。我用这个 post 作为起点:How to enable hibernate filter for sessionFactory.getCurrentSession()?
到目前为止我还没能拦截 Hibernate session:org.hibernate.internal.SessionFactoryImpl.SessionBuilderImpl.openSession().
我的方面 class 是这样的:
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");
}
}
这就是我试图拦截的所有classes/methods。我还通过测试 class/method 验证了方面 class 是否正常工作并且确实如此,因此 AOP 设置是正确的。 在调试时我可以看到系统触发了 org.hibernate.internal.SessionFactoryImpl.SessionBuilderImpl.openSession() 但不会触发我的拦截器? 我的 application.properties 文件包含此条目:
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
我错过了什么?
Hibernate 类 不是 Spring 组件,因此 Spring AOP 不适用于它们。如果你想拦截他们,我建议你切换到完整的AspectJ with load-time weaving。然后你也可以选择不使用 execution()
来操纵 Hibernate 的字节码,而是 call()
只会改变你自己的 类.