gpt4 book ai didi

spring-boot - Spring + Lombok + @SneakyThrows

转载 作者:行者123 更新时间:2023-12-04 12:51:37 28 4
gpt4 key购买 nike

我正在使用 @SneakyThrows Lombok我的 SpringBoot 中的功能项目。
当 CGLIB 代理实现时,我遇到了这个功能的问题
它抛出
java.lang.Exception:意外异常,
预期但是
.
它可以以某种方式修复吗?



提供例子。

有接口(interface)和两种实现。

public interface SneakyThrowsExample {
void testSneakyThrows();
}

简单的实现

import lombok.SneakyThrows;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component(value = "simpleSneakyThrowsExample")
public class SimpleSneakyThrowsExample implements SneakyThrowsExample {

@Override
@SneakyThrows
public void testSneakyThrows() {
throw new IOException();
}
}

@事务 实现。 CGLIB 将代理此实现。

import lombok.SneakyThrows;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;

@Component(value = "transactionalSneakyThrowsExample")
public class TransactionalSneakyThrowsExample implements SneakyThrowsExample {

@Override
@SneakyThrows
@Transactional
public void testSneakyThrows() {
throw new IOException();
}
}

创建@SpringBootTest 测试并注入(inject)这两个实现

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;

@RunWith(SpringRunner.class)
@SpringBootTest
public class DefaultSneakyThrowsExampleTest {

@Autowired
@Qualifier(value = "transactionalSneakyThrowsExample")
SneakyThrowsExample transactionalSneakyThrowsExample;

@Autowired
@Qualifier(value = "simpleSneakyThrowsExample")
SneakyThrowsExample simpleSneakyThrowsExample;

@Test(expected = IOException.class)
public void testSneakyThrowsSimple() throws Exception {
this.simpleSneakyThrowsExample.testSneakyThrows();
}

@Test(expected = IOException.class)
public void testSneakyThrowsTransactional() throws Exception {
this.transactionalSneakyThrowsExample.testSneakyThrows();
}
}

测试 testSneakyThrowsTransactional 因错误而失败

java.lang.Exception: Unexpected exception, expected<java.io.IOException> but was<java.lang.reflect.UndeclaredThrowableException>

at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:28)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.reflect.UndeclaredThrowableException
at fine.project.TransactionalSneakyThrowsExample$$EnhancerBySpringCGLIB$$57df642e.testSneakyThrows(<generated>)
at fine.project.DefaultSneakyThrowsExampleTest.testSneakyThrowsTransactional(DefaultSneakyThrowsExampleTest.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:19)
... 20 more
Caused by: java.io.IOException
at fine.project.TransactionalSneakyThrowsExample.testSneakyThrows(TransactionalSneakyThrowsExample.java:21)
at fine.project.TransactionalSneakyThrowsExample$$FastClassBySpringCGLIB$$e5429d83.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
... 31 more

最佳答案

当您使用 @事务 然后 Spring 将通过 AOP 代理为您的 bean 创建一个代理 - Spring Framework’s declarative transaction

UndeclaredThrowableException原因:

Thrown by a method invocation on a proxy instance if its invocation handler's invoke method throws a checked exception (a Throwable that is not assignable to RuntimeException or Error) that is not assignable to any of the exception types declared in the throws clause of the method that was invoked on the proxy instance and dispatched to the invocation handler.



隆博克 @SneakyThrows :

Can be used to sneakily throw checked exceptions without actually declaring this in your method's throws clause



这意味着您的 TransactionalSneakyThrowsExample.testSneakyThrows()抛出已检查异常(未在方法签名中的 throws 中声明)当实例包装在代理中时,这是非法行为

在这种情况下,您可以将预期异常更改为 Exception.class :

    @Test(expected = Exception.class)
public void testSneakyThrowsTransactional() throws Exception {
this.transactionalSneakyThrowsExample.testSneakyThrows();
}

或者您可以使用 ExpectedException.expectCause()检查 IOException.class在你的测试中,看看 JUnit expect a wrapped exception

关于spring-boot - Spring + Lombok + @SneakyThrows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47017259/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com