User.java未实例化示例
public class User {
public User() {
System.out.println("User实例已经创建!");
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
<beans:bean id="user" class="cn.spy.spring.source.code.User" lazy-init="true">
<beans:property name="name" value="zhangsan"></beans:property>
</beans:bean>
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
}
读取bean配置的lazy-init标签
读取lazy-init标签是伴随着读取bean标签是一样的,只是作为bean标签的子节点而已。使用Dom技术读取XML文档(ResouceLoader读取),得到Resouce对象,将Resouce对象转化为Document对象。获取Document中的Element元素对象都封装为BeanDefinition,将BeanDefinition添加到BeanDefinitionMap集合映射中,最终添加到Spring IOC的管理容器BeanFactory(具体是DefaultListBeanFactory)。
读取Element元素中lazy-init属性值
已经读取并加载到BeanFactory
执行lazy-init标签的配置
- 完成初始化工作,初始化剩余的单例bean(finishBeanFactoryInitialization)
// 完成初始化工作,初始化剩余的单例bean
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// 冻结bean的定义,注册的bean定义不允许被修改
beanFactory.freezeConfiguration();
// 初始化剩余非懒加载方式的单例
beanFactory.preInstantiateSingletons();
}
- 非懒加载方式下的预实例化单例(preInstantiateSingletons)
// 预实例化单例(非懒加载)
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
List<String> beanNames;
// 获取所有的Bean名称
synchronized (this.beanDefinitionMap) {
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
beanNames = new ArrayList<String>(this.beanDefinitionNames);
}
// 遍历bean,名称
for (String beanName : beanNames) {
// 遍历当前bean的父类bean,将父bean与当前bean结合
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// bean存在、为单例,不为懒加载才可以预实例化
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
}
}
在preInstantiateSingletons方法中,执行getBean方法实例化的前提必须是单例且非懒加载,所以我们设置了懒加载lazy-init为true,则没有执行实例化操作。而refresh()方法执行完也只是将bean的配置信息添加到了BeanFactory(DefaultListableBeanFactory)进行初始化而已。
解释示例:
所以上面示例中的User.java类就没有实例化,也就不会执行构造方法,而只是将User的bean配置信息加入到BeanFactory而已,等到getBean方法调用才会进行实例化。
网友评论