实例化

Spring如何解决循环依赖,你真的懂了?

对着背影说爱祢 提交于 2020-04-07 20:58:08
导读 前几天发表的文章 SpringBoot多数据源动态切换 和 SpringBoot整合多数据源的巨坑 中,提到了一个坑就是动态数据源添加@Primary接口就会造成循环依赖异常,如下图: 这个就是典型的构造器依赖,详情请看上面两篇文章,这里不再详细赘述了。本篇文章将会从源码深入解析Spring是如何解决循环依赖的?为什么不能解决构造器的循环依赖? 什么是循环依赖 简单的说就是A依赖B,B依赖C,C依赖A这样就构成了循环依赖。 循环依赖分为构造器依赖和属性依赖,众所周知的是Spring能够解决属性的循环依赖(set注入)。下文将从源码角度分析Spring是如何解决属性的循环依赖。 思路 如何解决循环依赖,Spring主要的思路就是依据三级缓存,在实例化A时调用doGetBean,发现A依赖的B的实例,此时调用doGetBean去实例B,实例化的B的时候发现又依赖A,如果不解决这个循环依赖的话此时的doGetBean将会无限循环下去,导致内存溢出,程序奔溃。spring引用了一个早期对象,并且把这个"早期引用"并将其注入到容器中,让B先完成实例化,此时A就获取B的引用,完成实例化。 三级缓存 Spring能够轻松的解决属性的循环依赖正式用到了三级缓存,在 AbstractBeanFactory 中有详细的注释。 /**一级缓存,用于存放完全初始化好的 bean,从该缓存中取出的

iOS 懒加载

寵の児 提交于 2020-04-07 13:16:08
1.懒加载基本 懒加载——也称为延迟加载,即在需要的时候才加载(效率低,占用内存小)。所谓懒加载,写的是其get方法. 注意:如果是懒加载的话则一定要注意先判断是否已经有了,如果没有那么再去进行实例化 2.使用懒加载的好处: (1)不必将创建对象的代码全部写在viewDidLoad方法中,代码的可读性更强 (2)每个控件的getter方法中分别负责各自的实例化处理,代码彼此之间的独立性强,松耦合 (3)只有当真正需要资源时,再去加载,节省了内存资源。 3.用法 声明一个属性 @property (nonatomic, retain) NSMutableArray *array; 重写getter方法 - (NSMutableArray *)array{ //判断是否已经有了,若没有,则进行实例化 这是重点,必须先判断 //切勿使用self.array,因为self.array会调用getter方法,造成死循环。 if (!_array) { _array = [[NSMutableArray alloc]init]; } return _array; } 用到的时候调用getter方法 NSLog(@" %p------%p ",_array,self.array); 这里的输出结果是酱紫:0x0------0x7f8eca810f30 ,这是为啥子嘞,用下划线访问的成员变量

Java对象实例化报错:java.lang.InstantiationException: com.bjbde.pay.model.BdModel.BdMemberApiConfig

三世轮回 提交于 2020-04-06 06:48:24
现象 开发中使用实体类创建对象时,报错: java.lang.InstantiationException: com.bjbde.pay.model.BdModel.BdMemberApiConfig 实例化对象的代码 public static <T> T map2Bean(Map<String, Object> source, Class<T> instance) { try { T object = instance.newInstance(); Field[] fields = object.getClass().getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); FieldName fieldName = field.getAnnotation(FieldName.class); if (fieldName != null){ field.set(object,source.get(fieldName.value())); }else { field.set(object,source.get(field.getName())); } } return object; } catch (InstantiationException |

Spring Bean的生命周期

旧城冷巷雨未停 提交于 2020-04-06 03:45:25
容器开始启动: 如果Spring容器中注册了实现BeanFactoryPostProcessor接口的容器后处理器,实例化该容器后处理器,即调用构造函数创建实例 如果Spring容器中注册了实现BeanFactoryPostProcessor接口的容器后处理器,就调用BeanFactoryPostProcessor.postProcessBeanFactory()方法 容器运行中: 如果Spring容器中注册了实现InstantiationAwareBeanPostProcessor接口的Bean后处理器,就执行该Bean后处理器的postProcessBeforeInstantiation方法。 实例化bean,即调用Bean的构造函数 如果Spring容器中注册了实现InstantiationAwareBeanPostProcessor接口的Bean后处理器,就执行该Bean后处理器的postProcessAfterInstantiation方法。 如果Spring容器中注册了实现InstantiationAwareBeanPostProcessor接口的Bean后处理器,就执行该Bean后处理器的postProcessProperties方法。 如果Spring容器中注册了实现InstantiationAwareBeanPostProcessor接口的Bean后处理器

C++单例模式

有些话、适合烂在心里 提交于 2020-04-06 02:37:05
单例模式是任何面向对象语言绕不过的,单例模式是很有必要的,接下来我用最朴素的语言来解释和记录单例模式的学习。 什么是单例模式? 单例模式就是一个类只能被实例化一次 ,更准确的说是 只能有一个实例化的对象的类。 创建一个单例模式的类(初想) 一个类只能有一个实例化的对象,那么这个类就要禁止别人new出来,或者通过直接定义一个对象出来 class CAR { public: CAR(){} ~CAR(){} }; CAR a; CAR *b = new CAR; 很明显这样的类可以被程序员用上面这两种方式实例化。那么考虑,如何禁止用上面的这两种方式实例化一个类呢? 如果把构造函数私有化,很明显上面这两种方法都会默认的去调用构造函数,当构造函数是private或者protected时,构造函数将无法从外部调用。 class CSingleton { private: CSingleton() { } }; int main() { CSingleton t; CSingleton *tt = new CSingleton; } 上面的代码选择了这样实例化类,很明显编译器会报错,因为私有化的构造函数无法被外部调用 error: ‘CSingleton::CSingleton()’ is private 既然构造函数是私有了,那么他就只能被类内部的成员函数调用

单例设计模式

岁酱吖の 提交于 2020-04-04 09:20:54
@ 目录 一、概念叙述 二、先看个问题 三、单例模式实现 (一)、饿汉模式 (二)、懒汉模式 (三)、双重校验锁 一、概念叙述 单例模式是一种常用的软件设计模式,使用单例模式,可以保证为一类只生成唯一的实例对象。也就是说,整个程序空间中,该类只存在一个实例对象。 二、先看个问题 我们通常在实例化对象是,通常是通过去new构造器方法获取一个类的实例化对象。这样就会出现一个问题:那就是每次创建的实例对象的内存地址都不一样。 public class Student { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } 接下来单例模式就可以解决这个问题。 三、单例模式实现 (一)、饿汉模式 package 单例模式; /** * 饿汉模式 * 1、初始化类对象 * 2、私有化构造器 * 3、通过静态方法还会 */ public class Student { // 初始化对象,当类加载时,就已经把student对象加载到了内存中 private static Student student = new Student(); private String name; // 第一步私有化构造器

C#文本操作

[亡魂溺海] 提交于 2020-04-04 00:06:44
1、使用FileStream读写文件 文件头: 复制代码 代码如下: using System; using System.Collections.Generic; using System.Text; using System.IO; 读文件核心代码: 复制代码 代码如下: byte[] byData = new byte[100]; char[] charData = new char[1000]; try { FileStream sFile = new FileStream("文件路径",FileMode.Open); sFile.Seek(55, SeekOrigin.Begin); sFile.Read(byData, 0, 100); //第一个参数是被传进来的字节数组,用以接受FileStream对象中的数据,第2个参数是字节数组中开始写入数据的位置,它通常是0,表示从数组的开端文件中向数组写数据,最后一个参数规定从文件读多少字符. } catch (IOException e) { Console.WriteLine("An IO exception has been thrown!"); Console.WriteLine(e.ToString()); Console.ReadLine(); return; } Decoder d = Encoding.UTF8

python之旅:元类metaclass

烈酒焚心 提交于 2020-04-02 05:53:08
廖老师元类:http://www.cnblogs.com/moyand/p/8868857.html 一 知识储备 exec:三个参数 参数一:字符串形式的命令 参数二:全局作用域(字典形式),如果不指定,默认为globals() 参数三:局部作用域(字典形式),如果不指定,默认为locals() #可以把exec命令的执行当成是一个函数的执行,会将执行期间产生的名字存放于局部名称空间中 g={ 'x':1, 'y':2 } l={} exec(''' global x,z x=100 z=200 m=300 ''',g,l) print(g) #{'x': 100, 'y': 2,'z':200,......} print(l) #{'m': 300} exec的使用 二 引子(类也是对象) class Foo: pass f1=Foo() #f1是通过Foo类实例化的对象 python中一切皆是对象,类本身也是一个对象,当使用关键字class的时候,python解释器在加载class的时候就会创建一个对象(这里的对象指的是类而非类的实例),因而我们可以将类当作一个对象去使用,同样满足第一类对象的概念,可以: 把类赋值给一个变量 把类作为函数参数进行传递 把类作为函数的返回值 在运行时动态地创建类 上例可以看出f1是由Foo这个类产生的对象,而Foo本身也是对象

单例模式

十年热恋 提交于 2020-04-01 07:56:29
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。 注意: 1、单例类只能有一个实例。 2、单例类必须自己创建自己的唯一实例。 3、单例类必须给所有其他对象提供这一实例。 保证一个类仅有一个实例,并提供一个访问它的全局访问点。 主要解决: 一个全局使用的类频繁地创建与销毁。 何时使用: 当您想控制实例数目,节省系统资源的时候。 如何解决: 判断系统是否已经有这个单例,如果有则返回,如果没有则创建。 关键代码: 构造函数是私有的。 应用实例: 1、一个党只能有一个书记。 2、Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。 3、一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。 优点: 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。 2、避免对资源的多重占用(比如写文件操作)。 缺点: 没有接口,不能继承

SSM框架中IoC、DI与AOP的理解

断了今生、忘了曾经 提交于 2020-03-30 13:06:38
  框架封装了普通项目中程序员需要重复书写的代码和调用过程,就比如说在传统的jsp项目中,我们的controller接收到前端的请求然后程序员就需要去开发Dao层,里面还涉及数据库的连接和存储过程的代码,大部分都是冗余的代码,而有了SSM框架后极大的简化了程序猿在controller以下层的开发,只需要一个service层和mapper层就行了,mapper层用来连接mapper.xml文件的,而直接用mapper.xml做sql语句的开发就行了,而数据库连接的和存储的过程都直接由Mybatis负责了,你只需要负责传递形参和接收返回数据就行了,这样就完成了一次完整的数据库交互! 1.1、IoC是什么   Ioc— Inversion of Control ,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。如何理解好Ioc呢?理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转,哪些方面反转了”,那我们来深入分析一下: ● 谁控制谁,控制什么: 传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么