这是源类:
@Data
@EqualsAndHashCode(callSuper = false)
@AllArgsConstructor
@NoArgsConstructor
@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
@JsonSerialize(as = RequestContext.class)
public class RequestContext implements Serializable {
private static final long serialVersionUID = 1L;
private String statusCode;
private String statusType;
private String txnId;
private int channelId;
private String channel;
}
这些是目标类及其父类:
@Data
@EqualsAndHashCode(callSuper = false)
@AllArgsConstructor
@NoArgsConstructor
@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
@JsonSerialize(as = Transaction.class)
public class Transaction extends TransactionBase implements Serializable {
private static final long serialVersionUID = 1L;
private Actors actors = Actors.SENDER;
private PartnerMaster senderPartner;
private PartnerMaster receiverPartner;
private PartnerMaster userPartner;
private UserMaster senderUser;
private UserMaster receiverUser;
private WalletAction adjustmentType;
private BigDecimal netAmount = BigDecimal.ZERO;
private BigDecimal amount = BigDecimal.ZERO;
private BigDecimal rollbackAmount = BigDecimal.ZERO;
private Charges charges = new Charges();
private List<SystemWalletMaster> systemWallets = new ArrayList<>();
private List<SystemCdrBean> systemCdr = new ArrayList<>();
private List<Items> products;
/** generic params for dynamic values. **/
private HashMap<String, Object> genericParams = new HashMap<>();
}
@Data
@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor
@AllArgsConstructor
public class TransactionBase extends TransactionFlags implements Serializable {
private static final long serialVersionUID = 1L;
private int channelId;
private String channel;
private String mvnoId;
private ServiceMaster service = new ServiceMaster();
private String featureId;
private String statusCode;
private String statusCodeReceiver;
private String statusType;
private String txnType;
private String message;
private String txnId;
private String requestId;
private long duration;
private TransactionCommon transactionCommon;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TransactionFlags implements Serializable {
private static final long serialVersionUID = 1L;
/** flags . **/
private boolean rollback;
private boolean adjustment;
private boolean adjustmentSystem;
private boolean isWhitelisted;
private boolean adjustCommission;
private boolean adjustFee;
private boolean adjustSystemCommission;
private boolean adjustSystemFee;
private boolean isLimitExists;
private boolean isLimitAllServices;
private boolean isApprovalEnabled;
}
豆子复制:
@Component
@Slf4j
public class RequestInterceptor implements HandlerInterceptor {
@Autowired
private Transaction transaction;
@Autowired
private RequestContext requestContext;
@Autowired
private UserContext userContext;
@Autowired
private CopyPropertyUtils copyPropertyUtils;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if (log.isDebugEnabled())
log.debug("{}Inside MFS Builder, building Transaction request", CONVERTER);
copyPropertyUtils.copy(requestContext, transaction);
..............
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// No implementation is done in post handle of the intercepter
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
..................
}
}
当我们尝试将
RequestContext
复制到 Transaction
时,我们收到此错误
java.lang.IllegalArgumentException: object is not an instance of declaring class
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[?:?]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[?:?]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:352) ~[spring-aop-6.1.1.jar:6.1.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.1.1.jar:6.1.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.1.1.jar:6.1.1]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765) ~[spring-aop-6.1.1.jar:6.1.1]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:137) ~[spring-aop-6.1.1.jar:6.1.1]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124) ~[spring-aop-6.1.1.jar:6.1.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.1.jar:6.1.1]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765) ~[spring-aop-6.1.1.jar:6.1.1]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:717) ~[spring-aop-6.1.1.jar:6.1.1]
at com.sixdee.mfs.base.beans.Transaction$$SpringCGLIB$$0.setChannel(<generated>) ~[classes/:?]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[?:?]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[?:?]
接下来是:
[2m2024-03-08T12:37:20.803+05:30[0;39m [31mERROR[0;39m [35m20264[0;39m [2m---[0;39m [2m${sys:LOGGED_APPLICATION_NAME}[nio-9110-exec-1][0;39m [36mc.s.d.b.e.ResponseErrorHandler [0;39m [2m:[0;39m Resource Not Found : object is not an instance of declaring class CLASS jdk.internal.reflect.NativeMethodAccessorImpl LINE -2
[2m2024-03-08T12:37:20.836+05:30[0;39m [33m WARN[0;39m [35m20264[0;39m [2m---[0;39m [2m${sys:LOGGED_APPLICATION_NAME}[nio-9110-exec-1][0;39m [36m.m.m.a.ExceptionHandlerExceptionResolver[0;39m [2m:[0;39m Resolved [org.springframework.beans.FatalBeanException: Could not copy property 'channel' from source to target]
[2m2024-03-08T12:37:20.836+05:30[0;39m [32mDEBUG[0;39m [35m20264[0;39m [2m---[0;39m [2m${sys:LOGGED_APPLICATION_NAME}[nio-9110-exec-1][0;39m [36mc.s.m.b.s.e.EventManager [0;39m [2m:[0;39m Event management is in progress...
[2m2024-03-08T12:37:20.836+05:30[0;39m [31mERROR[0;39m [35m20264[0;39m [2m---[0;39m [2m${sys:LOGGED_APPLICATION_NAME}[nio-9110-exec-1][0;39m [36mo.s.w.s.HandlerExecutionChain [0;39m [2m:[0;39m HandlerInterceptor.afterCompletion threw exception
org.springframework.aop.AopInvocationException: AOP configuration seems to be invalid: tried calling method [public java.lang.String com.sixdee.mfs.base.beans.Transaction.toString()] on target [RequestContext(statusCode=DFS100, statusType=F, txnId=168421046664246, channelId=1, channel=PORTAL)]
目标 (
Transaction
) 中所需的所有属性均从其父级 TransactionBase
扩展。
Transaction
,则不会出现错误。new RequestContext()
复制到 new Transaction()
而不是自动装配的 beans 时,没有错误。@Scope
注释时,副本就可以工作了。Transaction
的.class文件,发现没有继承的方法。Transaction
的所有注释都给了TransactionBase
,错误仍然发生。我们无法找到导致此问题的原因,无论是源问题(Point-3)还是目标问题(Point-1),我们只能了解其中之一对象不可用,属性名称和类型也相同。根据@M的评论。 Deinum 在这篇post中我相信问题出在
org.springframework.beans.BeanUtils
,但答案却说了别的。
我们在某些场景中使用
@Autowired
,在其他一些场景中使用@AllArgsConstructor
进行依赖注入,这会导致任何问题吗?另外,RequestContext
是父级maven项目中的一个bean,其他的都在子级maven项目中,这取决于父级。
版本
Java 17
Spring Boot 3.2.0
当您使用 ScopedProxyMode.TARGET_CLASS 时,它将使用 CGLIB 创建基于类的代理。因此 Transaction 和 RequestContext 类型的对象不是真正的实例,它们是具体类的代理,就像 Andrew 和 M.Deinum 在评论部分中所说的那样。您需要使用具体实现而不是代理。