由于spring注入的代理副作用,AOP无法捕获spring中的DAO异常
其目的是处理所有持久性异常,并将其包装为简单的通用异常,以便服务层可以轻松地处理它们 解决方案是使用AOP拦截来自DAO实现的异常。以下是spring配置:由于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">
<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