使用Spring注解自动应用Hibernate拦截器?

7

在我的服务类中,我需要可用的Hibernate会话。目前,我在beans.xml文件中进行如下配置:

<bean id = "userDao" class="org.springframework.aop.framework.ProxyFactoryBean">
 <property name="target">
   <ref bean="userDaoTarget" />
 </property>

 <property name="proxyInterfaces">
   <value>com.app.dao.UserDao</value>
 </property>

 <property name="interceptorNames">
   <list>
     <value>hibernateInterceptor</value>
   </list>
 </property>

 <qualifier value="proxy" />
</bean>

...

<bean id="hibernateInterceptor" 
   class="org.springframework.orm.hibernate3.HibernateInterceptor">
 <property name="sessionFactory">
   <ref bean="sessionFactory" />
 </property>
<bean>

我正在使用注解替代XML,我想知道是否有一种方法可以使用它们来配置代理,就像我上面所述的包括Hibernate拦截器?如果没有 - 是否有一种方法可以减少XML的数量(有大约7个DAO会让它非常杂乱)

2个回答

8

好的,让我们开始吧。你说:

我正在转向使用注解而非XML

按照以下方式启用一个方面:

package br.com.ar.aop;

@Aspect
public class HibernateInterceptorAdvice {

     @Autowired
     private HibernateInterceptor hibernateInterceptor;

     /**
       * I suppose your DAO's live in com.app.dao package
       */
     @Around("execution(* com.app.dao.*(..))")
     public Object interceptCall(ProceedingJoinPoint joinPoint) throws Throwable {
         ProxyFactory proxyFactory = new ProxyFactory(joinPoint.getTarget());
         proxyFactory.addAdvice(hibernateInterceptor);

         Class [] classArray = new Class[joinPoint.getArgs().length];
         for (int i = 0; i < classArray.length; i++)
             classArray[i] = joinPoint.getArgs()[i].getClass();

         return
             proxyFactory
                 .getProxy()
                 .getClass()
                 .getDeclaredMethod(joinPoint.getSignature().getName(), classArray)
                 .invoke(proxyFactory.getProxy(), joinPoint.getArgs());
     }

}

请记住,只有当DAO实现了某个接口时才能正常工作(例如,UserDAOImpl实现了UserDAO)。在这种情况下,Spring AOP使用JDK动态代理。如果您没有任何接口,可以依靠您的IDE通过使用提取接口(Extract interface)来重构代码。

将您的XML声明如下(请注意我正在使用Spring 2.5 XSD模式):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
                        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
                        http://www.springframework.org/schema/context 
                        http://www.springframework.org/schema/context/spring-context-2.5.xsd 
                        http://www.springframework.org/schema/aop  
                        http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
    <!--SessionFactory settings goes here-->
    <bean class="org.springframework.orm.hibernate3.HibernateInterceptor">
        <property name="sessionFactory" ref="sessionFactory"/>
    <bean>
    <!--To enable AspectJ AOP-->
    <aop:aspectj-autoproxy/>
    <!--Your advice-->
    <bean class="br.com.ar.aop.HibernateInterceptorAdvice"/>
    <!--Looks for any annotated Spring bean in com.app.dao package-->
    <context:component-scan base-package="com.app.dao"/>
    <!--Enables @Autowired annotation-->
    <context:annotation-config/>
</beans>

在使用Spring库时,不要忘记将classpath加入到代码中。

<SPRING_HOME>/lib/asm
<SPRING_HOME>/lib/aopalliance
<SPRING_HOME>/lib/aspectj

谢谢 - 这正是我所需要的! - Robert Wilson

0

看一下@Autowired注解。


1
除非我误解了,否则您不能使用Autowired添加拦截器? - Robert Wilson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接