聊一聊new对象与Spring对bean的初始化的差别
new对象与Spring对bean初始化差别
这个问题是一次我将老系统代码迁移到基于Spring构建的新系统中时遇到的,老代码中有很多地方使用了new方法来初始化对象,当时也没有特别注意,最后联调的时候发现所有new出来的对象中使用Autowired自动依赖注入的属性全都抛出了NullPointerException。
什么意思呢?
@Component
Class A {
...
}
@Component
Class B {
...
}
@Component
Class C {
@Autowired
A a;
@Autowired
B b;
}
当我使用C c = new C()时,c中的a和b都是null,也就是无法完成注入。
说实话,在联调的那一刻我有一瞬间是懵逼的,但现在回想起来,哦,真是太傻了。
简单来理解
Spring首先会通过new方法创建一个对象,然后去完成属性的填充,而这种填充在我们外界看来是“自动”的;而我们直接通过new方法创建对象时,是没有谁去完成属性的填充的,因而内部属性值全为null。
Spring类的注入和new简单理解
springboot
main.run
方法进入refreshContext
refresh
finishBeanFactoryInitialization
(完成beanFactory的初始化)preInstantiateSingletons
(初始化单例)getBean
(获取Bean)doGetBean
createBean
doCreateBean
(此方法内部会createBean,创建bean即构造方法执行)populateBean
(进行autowired自动注入)applyPropertyValues
(进行属性注入)
PS:new对象,不能导致对象依赖的注入属性自动赋值,只有对对象进行注入,对象依赖的注入属性才能赋值;
且注入的属性不能在构造函数中操作,因为bean没有创建完成,属性也没有注入,此时是为null的
问题:spring默认是单例模式,还有必要创建单例类吗?
自己理解:有必要,如果不使用autowired进行自动注入,使用new操作还是可以生成多个对象,
spring的单例是针对自动注入
例子:
@Component
public class CxfClient{undefined
@Value("${address }")
private String address;
private CxfClient(){undefined
System.out.println(address ); //此时为null.bean没有加载完成,属性也没有加载
}
public void createClient(){undefined
System.out.println(address );//此时为配置文件中的值
}
private static class SingletonHolder {undefined
private static final CxfClient INSTANCE = new CxfClient();
}
public static final CxfClient getInstance() {undefined
return SingletonHolder.INSTANCE;
}
}
public class Test{undefined
@Autowired
private CxfClient cxfClient;
public void testClient(){undefined
CxfClient.getInstance().createClient();//打印为null.无法注入
cxfClient.createClient();//打印为配置文件中的值
}
}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341