本文来说下spring容器管理对象和new对象之间的区别与联系
文章目录
流程图说明Spring注入的对象和new的对象区别
普通的创建new对象
在获取对象时都是采用new的方式,是属于主动的
交由spring ioc容器进行管理
spring在获取对象时,同时跟工厂要,有工厂就查找或者创建对象,是属于被动的
Spring的 IOC 容器比New对象究竟好在哪
ioc的思想最核心的地方在于,资源不由使用资源的双方管理,而由不使用资源的第三方管理,这可以带来很多好处。
- 资源集中管理,实现资源的可配置和易管理。
- 降低了使用资源双方的依赖程度,也就是我们说的耦合度。
IOC思想
java程序中的每个业务逻辑至少需要两个或以上的对象来协作完成,通常,在使用其他的合作对象时,均要使用像new object这样的语法来完成合作对象的申请工作。你会发现:对象间的耦合度高了。而IOC的思想是:Spring容器来实现这些相互依赖对象的创建、协调工作。对象只需要关心业务逻辑本身就可以了。IOC是基于java的反射机制以及工厂模式实现的。
Inversion of Control(控制反转)是一种设计思想,就是容器控制应用程序所需要外部资源的创建和管理,然后将其反转给应用程序。对象及其依赖对象的创建及维护都不需要在应用程序中实现,将其交给IOC容器去管理。传统的开发中,我们自己在对象内部创建依赖对象并注入当前对象,完成依赖关系的维护;对于IOC而言,它强调是将主动变为被动,由IOC容器来负责依赖对象的创建和查找,由IOC容器来进行注入组合对象,我们只需要在相关的配置文件中维护对象之间的依赖关系即可。
new对象
平时new A()时候是要import包地址的,这就已经写死了,以后这个引用就死死的指向了那个类,想改变很麻烦,用ac.getbean(“A”)就没引入包,也就是所谓的不依赖 (就是跟那类A没关系),它只从容器找那个叫A的类,至于你给我的是啥,看容器中咋配置。
举个例子:比如说是个很常用的dao类,开始你new的很开心,万一以后需求大改,数据库mysql换db2了,这个dao文件基本就得重写,如果这个类已经封装编译为class文件,不能改了怎么办。又或者你实例化了一个常用接口。
原来那个实现类A不好,要换成B做他的实现类,重写他的方法。你就得把项目中所有实例化的地方都找出来,再改成B(大项目用了很多的话你就一个一个改类似,万一漏了就是不小的bug)。用ioc就没这个麻烦,直接在配置文件中将叫A的bean指向你新写的类就可以。
new 对象里面使用自动注入对象会报空指针异常
根本原因在于当Spring框架帮我们管理的时候就会自动的初始化接下来会用到的属性,而通过new对象的方式,在该new对象中使用到的一些实例就需要自己去做初始化,否则就会报空指针异常。
如下例子所示:TestService 通过@Autowired注入,那么Spring容器就会自动注入TestService 中会用到的TestDao。
@RestController
@RequestMapping(value = "/test")
public class TestController {
@Autowired
private TestService testService;
@RequestMapping(value = "/print",method = RequestMethod.GET)
public void test() {
testService.test();
}
}
@Service
public class TestService {
@Autowired
private TestDao testDao;
public void test() {
testDao.test();
}
}
如果TestService 通过new对象方式新建的话,Spring容器就不会自动注入TestDao,此时testDao为null,会报空指针异常。此时就需要在TestService中自己new一个TestDao对象。如例二所示。
@RestController
@RequestMapping(value = "/test")
public class TestController {
private TestService testService = new TestService ();
@RequestMapping(value = "/print",method = RequestMethod.GET)
public void test() {
testService.test();
}
}
@Service
public class TestService {
@Autowired
private TestDao testDao;
public void test() {
TestDao testDao = new TestDao ();
testDao.test();
}
}
小结
在程序启动时,Spring会按照一定的加载链来加载并初始化Spring容器中的组件。
例如:在A中注入B,B中注入C。在A中调用B,来使用B中调用C的方法时,如果不采用自动注入,而是使用new对象方式的话,就会报空指针异常(因为B中的C并没有被初始化)。
本文小结
其实spring容器管理对象和new对象,最重要的区别就是IOC容器可以看作第三方的中介,管理着所有的bean以及bean之间的关系,当程序中需要对象的时候,直接去容器中拿就可以了,这样就极大的降低了程序的耦合度,利于代码的编写与维护,所以在程序中,一般看到的都是controller,dao和service这3层。如果直接new的话,程序之间是强耦合,因为使用一个类的时候,是需要导包的,这样维护与修改并不是十分的方便。