精华内容
下载资源
问答
  • "不允许循环文件引用" 错误,造成工程可以生成,但是无法发布,这是由于自动以控件(或页面)的目录造成的,它们或许和一些类的名称有冲突,更改他们存在的路径,问题解决。

    有时候自定义控件的"未知的服务器标记"以及母板页中的 "不允许循环文件引用" 错误,造成工程可以生成,但是无法发布,这是由于自动以控件(或页面)的目录造成的,它们或许和一些类的名称有冲突,更改他们存在的路径,问题解决。

    展开全文
  • service层循环引用问题

    2017-11-06 03:19:49
    但是为了数据完整,在后一步存在的情况下前一步是不允许修改删除的,所以前一步又需要引入后一步的service,这就带来了循环引入的问题。 想要解决循环引入,写很多@Lazy感觉又非常的麻烦,想问问有什么好的办法吗?...
  • go 为什么不允许循环引用 曾经有人提议Go语言作者Rob Pike,想要在Go以后的版本去掉循环引入;Rob Pike坚决不同意。Rob Pike觉得假如你两个包之间存在循环引入的问题,那一定是你在设计之初就没考虑好模块的划分。 ...

    前言

    在项目中,我们或多或少都会遇到go的包循环引用的问题,类似这样
    import cycle
    这就让人很头疼,为什么在其他语言中都没见过这种错误呢?这我们就得来谈谈go的设计理念了。

    go 为什么不允许循环引用

    曾经有人提议Go语言作者Rob Pike,想要在Go以后的版本去掉循环引入;Rob Pike坚决不同意。Rob Pike觉得假如你两个包之间存在循环引入的问题,那一定是你在设计之初就没考虑好模块的划分。
    这样设计的好处:

    1. 加快编译速度
    2. 规范框架设计,使项目结构更加清晰明了

    定位循环引用

    如上图所示,想要定位到循环引用的具体文件,具体的代码位置是比较困难的,特别是当项目文件特别多的时候。这边有一个项目引用可视化的工具,可以查看包引用的关系godepgraph。可以生成如下的引用图:
    在这里插入图片描述
    感兴趣的可以自行查看更多的使用方式。

    使用interface来解决循环引用

    例子:包p1和包p2循环引用,包p1实现包p2的接口。

    目录结构

    目录结构

    包p1

    package p1
    
    import (
    	"fmt"
    
    	"../p2"
    )
    
    type SayHello struct{}
    
    func (*SayHello) SayHello() {
    	fmt.Println("i'm p1, hello!!!")
    }
    
    func (h *SayHello) SayHelloFromP2() {
    	pup := p2.New(h)
    	pup.SayP1Hello()
    }
    
    

    包p2

    package p2
    
    import (
    	"fmt"
    )
    
    type ISayHello interface {
    	SayHello()
    }
    
    type p2UseP1 struct {
    	realP1 ISayHello
    }
    
    // 如果不能直接使用p1,就把p1传过来,我给个interface接收下,我在内部使用
    func New(h ISayHello) *p2UseP1 {
    	return &p2UseP1{
    		h,
    	}
    }
    
    // p1 say hello
    func (p *p2UseP1) SayP1Hello() {
    	p.realP1.SayHello()
    }
    
    // p2 say hello
    func (p *p2UseP1) SayP2Hello() {
    	fmt.Println("i'm p2, hello!!!")
    }
    
    

    main

    package main
    
    import "./p1"
    
    // 测试:包的循环引用
    func main() {
    	var h p1.SayHello
    	h.SayHello() // i'm p1, hello!!!
    	h.SayHelloFromP2() // i'm p1, hello!!!
    }
    
    

    总结

    go 出现包循环引用的问题,首当其冲的就是程序结构没设计好,最好的方式就是在项目框架构建的时候,将各个模块设计好,避免出现该问题。当项目内容较少的时候,可以通过重构来重新梳理项目架构,但随着项目的规模扩大,重构的成本增加,不可能每次出现类似的问题都去重构代码,这样可能会得不偿失。尝试分层的设计,高层依赖于低层,低层不依赖于高层,在开发的过程中始终将这些理念记在心中。当两个包有紧密耦合关系时,最好将它们放到一个包内。实在不行的情况下,我们可以使用interface来解决包依赖的问题。

    展开全文
  • Spring中的循环依赖循环依赖条件解决方案Spring的一些容器不允许循环依赖出现的情况1、构造器注入2、多例对象的setter注入无法循环依赖数据结构支撑流程简单解析处理流程为什么需要二级缓存不支持循环依赖的原因提前...

    循环依赖条件

    对象之间彼此的相互引用
    例如A持有B对象,同时B也持有A对象
    在这里插入图片描述
    也存在多个对象相互引用;例如A持有B,B持有C,C持有A的情况。
    在这里插入图片描述

    解决方案

    Spring中解决循环依赖使用了三个缓存(即一二三级缓存),并且通过提前暴露对象的手段使未进行依赖注入的对象可用。

    Spring的一些容器

    在这里插入图片描述

    不允许循环依赖出现的情况

    当然了,并不是说任何时候都能允许循环依赖的出现。下面就简单说两种

    1、构造器注入

    A,B两个对象作为构造函数的参数传入,并在构造函数进行依赖注入;会导致不支持循环依赖。

    代码示例

    A 对象

    @Component
    public class A {
    
        private B b;
    
    	// 在构造器标注自动装配
        @Autowired
        public A(B b) {
            this.b = b;
        }
    }
    

    B 对象

    @Component
    public class B {
    
        private A a;
    
    	// 在构造器标注自动装配
        @Autowired
        public B(A a) {
            this.a = a;
        }
    }
    

    报出的错误

    经过简单的筛选,以下错误就是问题的核心。

    Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'a' defined in file [C:\DemoAndPirace\Spring\target\classes\com\flj\whilerefer\A.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'b' defined in file [C:\DemoAndPirace\Spring\target\classes\com\flj\whilerefer\B.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'a': Requested bean is currently in creation: Is there an unresolvable circular reference?
    Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'a' defined in file [C:\DemoAndPirace\Spring\target\classes\com\flj\whilerefer\A.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'b' defined in file [C:\DemoAndPirace\Spring\target\classes\com\flj\whilerefer\B.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'a': Requested bean is currently in creation: Is there an unresolvable circular reference?
    
    Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'b' defined in file [C:\DemoAndPirace\Spring\target\classes\com\flj\whilerefer\B.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'a': Requested bean is currently in creation: Is there an unresolvable circular reference?
    	
    Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'a': Requested bean is currently in creation: Is there an unresolvable circular reference?
    	
    

    核心问题

    Spring报错直接指出是否存在了循环依赖导致无法正常进行Bean的实例化

    在这里插入图片描述

    简单原理

    为什么通过构造器注入无法进行循环依赖呢?

    因为Spring在创建对象的时候还未实例化对象就要注入另一个对象了;注意,是实例化。

    当需要注入另一个对象的时候就需要去创建另一个对象;但是另一个对象也持有自己,所以形成了套娃。

    在这里插入图片描述

    2、多例对象的setter注入无法循环依赖

    第二种情况就是多例的Bean对象无法进行循环依赖

    代码示例

    A 对象

    @Component
    @Scope("prototype")
    public class A {
        @Autowired
        private B b;
    }
    

    B对象

    @Component
    @Scope("prototype")
    public class B {
    
        @Autowired
        private A a;
    }
    

    main方法,需要注意一定要去手动获取对象

    
    public class SpringCon {
        public static void main(String[] args) 
    
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnnotationConfig.class);
            // 一定要去获取Bean对象
            // 因为在Spring容器中,多例对象是用到的时候才去获取的
            // 如果不用该对象,那么不会创建;也就无法测试循环依赖
            Object a = context.getBean("a");
    
    
        }
    }
    

    异常错误

    Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'a': Unsatisfied dependency expressed through field 'b'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'b': Unsatisfied dependency expressed through field 'a'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'a': Requested bean is currently in creation: Is there an unresolvable circular reference?
    Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'b': Unsatisfied dependency expressed through field 'a'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'a': Requested bean is currently in creation: Is there an unresolvable circular reference?
    
    Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'a': Requested bean is currently in creation: Is there an unresolvable circular reference?
    
    

    无法循环依赖的原因

    因为在多例中,不知道要对哪个对象进行循环依赖。

    所以Spring在循环依赖的条件中就把多例排除出去了。

    后面源码会稍微讲一下。

    ===================================================

    以下的模块需要对Spring的生命周期有所简单的了解。

    大概从源码角度简单分析,涉及到的类还未贴出

    ===================================================

    数据结构支撑

    • 循环依赖使用了三个缓存结构来解决,并不是说一定要三个,其实一三就能解决,多个二级缓存只是为了提高效率;并且三级缓存是一个工厂对象

    • 其次,还涉及到了一个容器,这个容器是表示正在实例化的BeanDenfinition以及一个变量,就是允许提前暴露Bean实例。

    三个Map图示(从上到下分别是一二三级缓存)
    在这里插入图片描述

    在这里插入图片描述

    流程简单解析

    首先,要清楚:如果一个类中包含成员变量拥有引用类型,并且加上了@Autowire的注解,那么在进行依赖注入的时候一定会实例化对应的引用对象,即beanFactory.getBean(被引用的BeanName);

    循环依赖要涉及到Spring的IOC,DI,依赖注入的问题。

    简单说明一下Bean对象的创建:
    解析XML->通过无参构造器实例化对象->收集Bean对象的成员变量的注解->提前暴露Bean对象->依赖注入->放入一级缓存->后期销毁

    创建对象图例:
    在这里插入图片描述

    处理流程

    假设下面是A对象走的流程
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    此时,依赖注入就会触发到另一个对象B的创建,也是跟上面一样的。
    当B对象也进行依赖注入的时候,发现需要注入A,然后我们走到前面

    在这里插入图片描述
    在这里插入图片描述

    为什么需要二级缓存

    这里要说明一下为什么会有二级缓存这种东西
    我们可以看到,三级缓存返回的是一个工厂,ObjectFactory
    他的getObject方法比较复杂,所以直接将对象获取出来提取到一个中间缓存进行存放。

    这样,如果A注入了很多循环依赖对象,那么其他的Bean需要拿到A的实例只需要从二级缓存中拿取实例对象即可,不需要去三级缓存拿工厂在生成,避免了一些重复的繁琐操作。
    在这里插入图片描述

    不支持循环依赖的原因

    • 首先来解析构造函数
    1) 单例能够实现循环依赖是因为他已经实例化好了对象,只是没有给对象中的属性赋值,那么这个地址是永远都可以使用的

    2)而通过构造函数注入,就需要传入该对象才能成功的实例化对象,否则无法进行对象的实例化
    3) 小结:setter方法注入是已经实例化好了对象;构造器注入则是缺少实例化对象的条件,导致无法实例化,产生了死锁才报错

    • 多例不支持的原因

    1) 因为多例不能提前暴露对象,所以当第二次进来的时候,会发现我这个对象已经正在实例化了,所以报错了

    2)并且多例对象天生就具有懒加载
    在这里插入图片描述

    提前暴露对象的条件

    单例的,允许循环依赖,该单例对象正在实例化
    在这里插入图片描述

    展开全文
  • 二是预处器不允许访问类的成员数据,所以引入了内联函数。 •一般地,任何种类的循环都被认为太复杂而不扩展为内联函数。假如函数有许多语句,也不建议使用内联。假如要显式地或隐式地取函数地址,编译器也不能执行...

    一、内联函数

    •保持效率的一个方法是使用宏,但存在两个问题:一是宏看起来像一个函数调用。但并不总是这样。这样就隐藏了难以发现的错误。二是预处器不允许访问类的成员数据,所以引入了内联函数。

    •一般地,任何种类的循环都被认为太复杂而不扩展为内联函数。假如函数有许多语句,也不建议使用内联。假如要显式地或隐式地取函数地址,编译器也不能执行内联。内部链接的一个好处是这个名字可以放在一个头文件中而不用担心链接时发生冲突。那些通常放在头文件里的名字,如常量,内联函数,在默认情况下都是内部链接的。

    二、 静态数据成员:
    类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态数据成员。和其他数据成员一样,静态数据成员也遵守public/protected/private访问规则。同时,静态数据成员还具有以下特点:
    1.静态数据成员的定义。
    静态数据成员实际上是类域中的全局变量。所以,静态数据成员的定义(初始化)不应该被放在头文件中。
    2.静态数据成员被 类 的所有对象所共享,包括该类派生类的对象。即派生类对象与基类对象共享基类的静态数据成员。

    3.静态数据成员可以成为成员函数的可选参数,而普通数据成员则不可以。

    4.★静态数据成员的类型可以是所属类的类型,而普通数据成员则不可以。普通数据成员的只能声明为 所属类类型的 指针或引用。

    5静态成员函数不能访问一般的数据成员,而只能访问静态数据成员,也只能调用其他的静态成员函数。

    三、引用

    •当引用被创建时,它必须被初始化(指针则可以在任何时候被初始化)。

    •一旦一个引用被初始化为指向一个对象,它就不能改变为另一个对象的引用(指针则可以在任何时候指向另一个对象)。

    •不可能有NULL引用,必须确保引用是和一块合法的存储单元关联。

    展开全文
  • 弄透Block

    2019-06-11 01:40:38
    目标 ...Block:带有自动变量的匿名函数,它是C语言的拓展功能,之所以是扩展,是因为C语言不允许存在这样的匿名函数 匿名函数 匿名函数是指不带函数名称的函数 带有自动变量 这是因为Block...
  • 备忘录-js let const

    2020-07-06 10:30:51
    let 只在代码块内有效:{let a=1;...不允许在相同作用域,重复声明同一个变量 可以代替匿名立即执行函数表达式 // IIFE 写法 (function () { var tmp = ...; ... }()); // 块级作用域写法 { let tmp = ...; ...
  • Block定义:带有自动变量的匿名函数,它是C语言的拓展功能,之所以是扩展,是因为C语言不允许存在这样的匿名函数 匿名函数 匿名函数式指不带函数名称的函数 带有自定变量 Block拥有捕获外部变量的功能,在Block...
  • } 每个 case 后面,必须有 break 或者 goto,不允许贯穿。 Goto goto 语句将程序控制直接传递给标记语句。 for (int i = 0; i ; i++) for (int j = 0; j ; j++) if (myArray[i,j].Equals(myNumber)) goto Found; ...
  • es6基础知识总结

    2019-02-19 11:24:45
    let不允许在同一个作用域下声明已经存在的变量 for循环体现let父子作用域cosnt:拥有上面let的各项规则,同时拥有以下的规则声明必须赋值声明的常量储存简单的数据类型时不可改变其值,如果存储的是对象,那么引用不...
  • 容易造成死锁(循环引用) 关于for update慢问题思考 对于真正要用悲观锁的地方,还是要用,是避免了。我们目前只是换种上锁的方式而已。 从业务角度进行分析 是否出现此问题 锁的跨度太大,正确的加锁,...
  •  1008 试图引用不存在的符号。  1009 配置注册表数据库已损坏。  1010 配置注册表主键无效。  1011 无法打开配置注册表主键。  1012 无法读取配置注册表主键。  1013 无法写入配置注册表主键。 ...
  • Excel VBA实用技巧大全 附书源码

    热门讨论 2010-10-08 18:59:24
    04053引用多个非连续单元格区域的集合(循环处理) 04054引用多个单元格区域的交叉区域 04055获取计算公式的所有引用单元格 04056获取计算公式中引用的其他工作表单元格 04057获取某个单元格的从属单元格 04058引用...
  • javascript入门笔记

    2018-05-15 15:01:07
    在程序中,一旦声明好,就不允许被修改的数据 2、声明常量 const 常量名=值; 常量名在命名时采用全大写形式 作业: 1、声明一个变量 r ,来表示一个圆的半径,并赋值 2、声明一个常量PI ,来表示圆周率3.14 ...
  • 操作系统(内存管理)

    热门讨论 2009-09-20 12:55:25
    文中将为您提供如何管理内存的细节,然后将进一步展示如何手工管理内存,如何使用引用计数或者内存池来半手工地管理内存,以及如何使用垃圾收集自动管理内存。 为什么必须管理内存 内存管理是计算机编程最为基本的...
  • '因为数组的get方法不允许被赋值,所以不能像下面这样写 'set j.b.get(0)=json.add(j.b.get(0),"new","我会报错") json.add j.b.get(0),"new","我是新加的new我不会报错" json.add j.b.get(0),"new1","我是通过变量...
  • 文中将为您提供如何管理内存的细节,然后将进一步展示如何手工管理内存,如何使用引用计数或者内存池来半手工地管理内存,以及如何使用垃圾收集自动管理内存。 为什么必须管理内存 内存管理是计算机编程最为基本的...
  • switch()中不允许的数据类型是? 答:实型 4. 回答下面的问题(6分) (1).Void GetMemory(char **p, int num){ *p = (char *)malloc(num); } void Test(void){ char *str = NULL; GetMemory(&str, 100); strcpy(str, ...
  • javaSE代码实例

    2016-06-21 22:30:18
    9.7.2 不允许进行测试的情况 174 9.8 小结 175 第10章 构造器——对象制造的工厂 176 10.1 基础知识 176 10.1.1 编写构造器的语法规则 176 10.1.2 访问限制修饰符与构造器 176 10.1.3 构造器与返回...
  •  数据控制语言Data Controlling Language(DCL),用来控制数据库组件的存取允许、存取权限等。例如:GRANT、REVOKE、COMMIT、ROLLBACK等语句。  事务控制语言(Transactional Control Language,TCL),用于...
  • java面试题

    2018-04-27 19:55:38
    答:set 不允许重复,无序 list 允许重复,有序 map 成对的数据结构,键值必须具有唯一性 Servlet和CGI的区别? 答:Servlet与CGI的区别在于Servlet处于服务器进程中,它通过多线程方式允许其service方法,一个...
  • Python Cookbook

    2013-07-31 22:33:26
    15.4 允许XML-RPC服务被远程终止 541 15.5 SimpleXMLRPCServer的一些细节 542 15.6 给一个XML-RPC服务提供一个wxPython GUI 544 15.7 使用Twisted的Perspective Broker 546 15.8 实现一个CORBA服务和客户 549 ...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 142
精华内容 56
关键字:

不允许存在循环引用