实例化和初始化的区别 实例化:是对象创建的过程。比如使用构造方法new对象,为对象在内存中分配空间; 初始化:是为对象中的属性赋值的过程; 这个初始化和bean中的init-method初始化方法是两个概念 这里仅仅考虑单例bean
spring处理循环依赖的三种情况: 构造器的循环依赖:这种依赖spring是处理不了的,直接抛BeanCurrentlylnCreationException异常; 单例模式下的setter循环依赖:通过“三级缓存”处理循环依赖; 非单例循环依赖:无法处理;
单例模式下setter方式循环依赖处理
/**
* Cache of singleton objects: bean name –> bean instance
* 完成初始化的单例对象的cache(一级缓存)
*/
private final Map singletonObjects = new ConcurrentHashMap(256);
/**
* Cache of singleton factories: bean name –> ObjectFactory
* 进入实例化阶段的单例对象工厂的cache
* allowEarlyReference=true
* 加入singletonFactories的前提是执行了构造器(三级缓存)
*/
private final Map> singletonFactories = new HashMap>(16);
/**
* Cache of early singleton objects: bean name –> bean instance
* 完成实例化但是尚未初始化(属性填充)的,提前暴光的单例对象的Cache(二级缓存)
*/
private final Map earlySingletonObjects = new HashMap(16);
/** Names of beans that are currently in creation. */
// 这个缓存也十分重要,它表示bean创建过程中都会在里面呆着
// 它在Bean开始创建时放值,创建完成时会将其移出
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
ignoreDependencyInterface 自动装配时忽略该接口实现类中和setter方法入参相同的类型,也就是忽略该接口实现类中存在依赖外部的bean属性注入。
ignoreDependencyType 自动装配时忽略某个类或者接口的实现
A BeanDefinition describes a bean instance, which has property values, constructor argument values This is just a minimal interface: The main intention is to allow a {BeanFactoryPostProcessor} to introspect and modify property values and other bean metadata.
BeanDefinition及抽象基类属性介绍
scope
role
parentName
beanClassName
autowireMode
lazyInit
String... dependsOn,the names of the beans that this bean depends on being initialized
autowireCandidate,whether this bean is a candidate for getting autowired into some other bean
primary,whether this bean is a primary autowire candidate
instanceSupplier:
factoryBeanName
factoryMethodName
constructorArgumentValues
propertyValues
initMethodName
destroyMethodName
description
resolvableType
abstractFlag,whether this bean is "abstract", that is, not meant to be instantiated
resourceDescription
qualifiers,AutowireCandidateQualifier
methodOverrides
synthetic,Set whether this bean definition is 'synthetic', that is, not defined by the application itself (for example, an infrastructure bean such as a helper for auto- proxying, created through {<aop:config>})
2. Full-fledged classes
```latex
RootBeanDefinition,
ChildBeanDefinition,
GenericBeanDefinition,
注解相关AnnotatedBeanDefinition
AnnotatedGenericBeanDefinition,
ScannedGenericBeanDefinition,
ConfigurationClassBeanDefinition
参考:https://juejin.im/post/6844903974475137031
singleton
是spring容器中bean的默认作用域。它告诉容器仅创建和管理一个bean类实例。该单个实例存储在此类单例bean的缓存中,并且对该命名bean的所有后续请求和引用都返回该缓存的实例。
prototype
每次应用程序对Bean进行请求时,原型作用域都会创建一个新的Bean实例。
request
在请求范围中,容器为每个HTTP请求创建一个新实例。因此,如果服务器当前处理50个请求,那么容器最多可以有50个bean类的单独实例。对一个实例的任何状态更改对其他实例都是不可见的。一旦请求完成,这些实例就会被销毁。
session
在会话范围中,容器为每个HTTP会话创建一个新实例。因此,如果服务器有20个活动会话,那么容器最多可以有20个bean类的单独实例。在单个会话生命周期内的所有HTTP请求都可以访问该会话范围内相同的单个bean实例。 在会话范围内,对一个实例的任何状态更改对其他实例都是不可见的。一旦会话在服务器上被销毁/结束,这些实例就会被销毁。
application
应用程序作用域bean是每个ServletContext的单例对象,而单例作用域bean是每个ApplicationContext的单例对象。请注意,单个应用程序可能有多个应用程序上下文;用程序作用域bean作为ServletContext属性可见
websocket
websocket范围内的bean通常是单例的,并且比任何单独的WebSocket会话寿命更长。
自定义线程作用域
Spring还使用类SimpleThreadScope提供了非默认线程作用域。若要使用此作用域,必须使用CustomScopeConfigurer类将其注册到容器;对bean的每个请求都将在同一线程中返回相同的实例
本质上都是自动装配,就是在使用XML配置和使用注解来自动装配Bean的属性
// autowireMode
public interface AutowireCapableBeanFactory extends BeanFactory {
/**
* Constant that indicates no externally defined autowiring. Note that
* BeanFactoryAware etc and annotation-driven injection will still be applied.
* 通过显式设置ref 属性来进行装配(xml)
*/
int AUTOWIRE_NO = 0;
/**
* indicates autowiring bean properties by name
* (applying to all bean property setters).
*/
int AUTOWIRE_BY_NAME = 1;
/**
* indicates autowiring bean properties by type
* (applying to all bean property setters).
*/
int AUTOWIRE_BY_TYPE = 2;
/**
* indicates autowiring the greediest constructor that
* can be satisfied (involves resolving the appropriate constructor).
* 也是要根据constructor中的参数type
*/
int AUTOWIRE_CONSTRUCTOR = 3;
/**
* indicates determining an appropriate autowire strategy
* through introspection of the bean class.
* @deprecated as of Spring 3.0: If you are using mixed autowiring strategies,
* prefer annotation-based autowiring for clearer demarcation of autowiring needs.
*/
@Deprecated
int AUTOWIRE_AUTODETECT = 4;
@Autowired根据类型来自动注入,如果有多个可以配合@Qualifier,或者可以使用@Primary,或者可以使用@Priority注解进行优先级排序(有个int类型的属性value,可以配置优先级大小。数字越小的,就被优先匹配)
在Spring3.0之后,有效的自动装配策略分为
byType、byName、constructor
三种方式。注解Autowired默认使用byType来自动装配,如果存在类型的多个实例,先通过Primary和Priority注解来确定,如果也确定不了,最后通过byName。
@Resource如果指定了name属性, 那么就按name属性的名称装配;如果没有指定name属性, 那就按照要注入对象的字段名查找依赖对象;如果按默认名称查找不到依赖对象, 那么就按照类型查找。
Supplier回调方式
工厂方法初始化
构造函数自动注入初始化
默认构造函数初始化: 如果该bean没有配置lookup-method、replace-method或者@LookUp注解,则直接通过反射的方式实例化bean对象即可; 如果存在覆盖,则需要使用CGLIB进行动态代理,因为在创建代理的同时可将动态方法织入类中;
关关雎鸠,在河之洲。窈窕淑女,君子好逑。--[关雎]
> 可在下面留言(需要有 GitHub 账号)