*************************** APPLICATION FAILED TO START ***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
┌─────┐ | orderService defined in file [./target/classes/cn/xxx/spring/OrderService.class] ↑ ↓ | userService defined in file [./target/classes/cn/xxx/spring/UserService.class] └─────┘
Action:
Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2023-02-1914:36:13.133 ERROR 15885 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
*************************** APPLICATION FAILED TO START ***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
┌─────┐ | orderService defined in file [/Users/weiki/Desktop/workspace/yuan/yuanjava/build/classes/java/main/cn/yuanjava/service/OrderService.class] ↑ ↓ | userService defined in file [/Users/weiki/Desktop/workspace/yuan/yuanjava/build/classes/java/main/cn/yuanjava/service/UserService.class] └─────┘
Action:
Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
曾经很长一段时间(Spring 3.0 以前的版本),字段依赖是比较主流的一种编程方式,因为这种方式编写方便简洁,而且 Spring 也利用三层缓存解决了循环依赖问题,但后面因 Spring 不推荐字段依赖注入方式,并且在 github上也可以发现大部分的开源软件也不采用这种方式了,所以该方案也仅供参考不推荐,改造代码如下:
/** * Indicates whether a bean is to be lazily initialized. * * <p>May be used on any class directly or indirectly annotated with {@link * org.springframework.stereotype.Component @Component} or on methods annotated with * {@link Bean @Bean}. * * <p>If this annotation is not present on a {@code@Component} or {@code@Bean} definition, * eager initialization will occur. If present and set to {@code true}, the {@code@Bean} or * {@code@Component} will not be initialized until referenced by another bean or explicitly * retrieved from the enclosing {@link org.springframework.beans.factory.BeanFactory * BeanFactory}. If present and set to {@code false}, the bean will be instantiated on * startup by bean factories that perform eager initialization of singletons. * * <p>If Lazy is present on a {@link Configuration @Configuration} class, this * indicates that all {@code@Bean} methods within that {@code@Configuration} * should be lazily initialized. If {@code@Lazy} is present and false on a {@code@Bean} * method within a {@code@Lazy}-annotated {@code@Configuration} class, this indicates * overriding the 'default lazy' behavior and that the bean should be eagerly initialized. * * <p>In addition to its role for component initialization, this annotation may also be placed * on injection points marked with {@link org.springframework.beans.factory.annotation.Autowired} * or {@link javax.inject.Inject}: In that context, it leads to the creation of a * lazy-resolution proxy for all affected dependencies, as an alternative to using * {@link org.springframework.beans.factory.ObjectFactory} or {@link javax.inject.Provider}. * Please note that such a lazy-resolution proxy will always be injected; if the target * dependency does not exist, you will only be able to find out through an exception on * invocation. As a consequence, such an injection point results in unintuitive behavior * for optional dependencies. For a programmatic equivalent, allowing for lazy references * with more sophistication, consider {@link org.springframework.beans.factory.ObjectProvider}. * * @author Chris Beams * @author Juergen Hoeller * @since 3.0 * @see Primary * @see Bean * @see Configuration * @see org.springframework.stereotype.Component */ @Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public@interface Lazy {
/** * Whether lazy initialization should occur. */ booleanvalue()defaulttrue;
// org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor#intercept classCglibAopProxyimplementsAopProxy, Serializable { privatestaticclassDynamicAdvisedInterceptorimplementsMethodInterceptor, Serializable { public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)throws Throwable { ObjectoldProxy=null; booleansetProxyContext=false; Objecttarget=null; TargetSourcetargetSource=this.advised.getTargetSource(); try { if (this.advised.exposeProxy) { // Make invocation available if necessary. oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } // Get as late as possible to minimize the time we "own" the target, in case it comes from a pool... // 获取被代理的对象 target = targetSource.getTarget(); Class<?> targetClass = (target != null ? target.getClass() : null); List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); Object retVal; // Check whether we only have one InvokerInterceptor: that is, // no real advice, but just reflective invocation of the target. if (chain.isEmpty() && CglibMethodInvocation.isMethodProxyCompatible(method)) { // We can skip creating a MethodInvocation: just invoke the target directly. // Note that the final invoker must be an InvokerInterceptor, so we know // it does nothing but a reflective operation on the target, and no hot // swapping or fancy proxying. Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); // 通过反射调用被代理对象的方法 retVal = invokeMethod(target, method, argsToUse, methodProxy); } else { // We need to create a method invocation... retVal = newCglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed(); } retVal = processReturnType(proxy, target, method, retVal); return retVal; }catch (Exception e){} } } }