Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
由于spring注入的代理副作用,AOP无法捕获spring中的DAO异常_Spring_Aop_Dao - Fatal编程技术网

由于spring注入的代理副作用,AOP无法捕获spring中的DAO异常

由于spring注入的代理副作用,AOP无法捕获spring中的DAO异常,spring,aop,dao,Spring,Aop,Dao,其目的是处理所有持久性异常,并将其包装为简单的通用异常,以便服务层可以轻松地处理它们 解决方案是使用AOP拦截来自DAO实现的异常。以下是spring配置: <bean id="DBExceptions" class="com.dao.impl.DAOExceptionTranslator" /> <aop:config> <aop:aspect id="dbExceptionsAspect" ref="DBExceptions">

其目的是处理所有持久性异常,并将其包装为简单的通用异常,以便服务层可以轻松地处理它们

解决方案是使用AOP拦截来自DAO实现的异常。以下是spring配置:

<bean id="DBExceptions" class="com.dao.impl.DAOExceptionTranslator" />
    <aop:config>
        <aop:aspect id="dbExceptionsAspect" ref="DBExceptions">
            <aop:after-throwing throwing="ex"
                pointcut="execution(* com.dao.impl.*.*(*))" method="doDAOActions" />
        </aop:aspect>
    </aop:config>
下面是使用DAO的代码:

private UserDAO userDAO;
public User getUserById(int id) throws UserServiceException {
        try {
            Object user = userDAO.findById(User.class, id);
...
userDAO的实现是由spring注入的,但是对于正常的db异常,它可以被拦截,而对于连接异常,它失败了

我认为,因为在spring注入DAO实现之前,它将首先构造连接,但它失败了,所以它没有调用目标操作

我想截获DAO的所有异常,如何通过spring注入解决代理的副作用

以下是两个不同的堆栈:

数据库逻辑错误:

UserDAOImpl.findUserByUsername(String) line: 23 
    NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]  
    NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39  
    DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25  
    Method.invoke(Object, Object...) line: 597  
    AopUtils.invokeJoinpointUsingReflection(Object, Method, Object[]) line: 309 
    ReflectiveMethodInvocation.invokeJoinpoint() line: 183  
    ReflectiveMethodInvocation.proceed() line: 150  
    AspectJAfterThrowingAdvice.invoke(MethodInvocation) line: 55    
    ReflectiveMethodInvocation.proceed() line: 172  
    TransactionInterceptor.invoke(MethodInvocation) line: 110   
    ReflectiveMethodInvocation.proceed() line: 172  
    ExposeInvocationInterceptor.invoke(MethodInvocation) line: 89   
    ReflectiveMethodInvocation.proceed() line: 172  
    JdkDynamicAopProxy.invoke(Object, Method, Object[]) line: 202   
    $Proxy17.findUserByUsername(String) line: not available 
    UserService.getUser(String) line: 74
但如果是DB连接错误:

at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:382)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:335)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:105)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy17.findUserByUsername(Unknown Source)
    at com.service.UserService.getUser(UserService.java:74)
如何解决这个问题


解决方案是指示每个代理的顺序,更改为

<aop:config>
        <aop:aspect id="dbExceptionsAspect" ref="DBExceptions" order="1">
            <aop:after-throwing throwing="ex"
                pointcut="execution(* com.dao.impl.*.*(*))" method="doDAOActions" />
        </aop:aspect>
    </aop:config>

您应该在服务方法上移动@Transactional注释。当用@Transaction注释一个类时,Spring将从中创建一个代理


问题是@Transactional拦截器(代理)尝试启动事务,但失败了,因为没有与数据库的连接。DAOExceptionTranslator未截获的错误,因为它在截获的代码之前执行。。

解决方案是指示每个代理的顺序。添加关键字顺序后,将首先调用DBExceptions代理,更改后查看堆栈。是的,这是另一种方式。但请注意,通常最好将@Transactional注释保留在服务层上,以保证跨多个Dao层调用的事务边界。谢谢,我们将检查服务层事务控制。
<aop:config>
        <aop:aspect id="dbExceptionsAspect" ref="DBExceptions" order="1">
            <aop:after-throwing throwing="ex"
                pointcut="execution(* com.dao.impl.*.*(*))" method="doDAOActions" />
        </aop:aspect>
    </aop:config>
DAOExceptionTranslator.doDAOActions(Exception) line: 12 
    NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]  
    NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39  
    DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25  
    Method.invoke(Object, Object...) line: 597  
    AspectJAfterThrowingAdvice(AbstractAspectJAdvice).invokeAdviceMethodWithGivenArgs(Object[]) line: 621   
    AspectJAfterThrowingAdvice(AbstractAspectJAdvice).invokeAdviceMethod(JoinPointMatch, Object, Throwable) line: 603   
    AspectJAfterThrowingAdvice.invoke(MethodInvocation) line: 59    
    ReflectiveMethodInvocation.proceed() line: 172  
    ExposeInvocationInterceptor.invoke(MethodInvocation) line: 89   
    ReflectiveMethodInvocation.proceed() line: 172  
    JdkDynamicAopProxy.invoke(Object, Method, Object[]) line: 202   
    $Proxy17.findUserByUsername(String) line: not available 
    UserService.getUser(String) line: 74