Spring中Bean定义、作用域、管理问题

参考
https://www.cnblogs.com/cainiaotuzi/p/7994650.html
https://www.cnblogs.com/cainiaotuzi/p/7994598.html

一、Bean的定义

<beans…/>元素是Spring配置文件的根元素,<beans…/>元素可以包含多个<bean…/>子元素,每个<bean…/>元素可以定义一个Bean实例,每一个Bean对应Spring容器里的一个Java实例定义Bean时通常需要指定两个属性。

  • Id:确定该Bean的唯一标识符,容器对Bean管理、访问、以及该Bean的依赖关系,都通过该属性完成。Bean的id属性在Spring容器中是唯一的。

  • Class:指定该Bean的具体实现类。注意这里不能使接口。通常情况下,Spring会直接使用new关键字创建该Bean的实例,因此,这里必须提供Bean实现类的类名。

Spring容器集中管理Bean的实例化,Bean实例可以通过BeanFactory的getBean(String beanid)方法得到。BeanFactory是一个工厂,程序只需要获取BeanFactory引用,即可获得Spring容器管理全部实例的引用。程序不需要与具体实例的实现过程耦合。大部分Java EE应用里,应用在启动时,会自动创建Spring容器,组件之间直接以依赖注入的方式耦合,甚至无须主动访问Spring容器本身。

当我们在配置文件中通过方法配置一个Bean时,这样就需要该Bean实现类中必须有一个无参构造器。

二、容器中Bean的作用域

当通过Spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定的作用域。

Spring支持5种作用域:

  • Singleton:单例模式。在整个SpringIoC容器中,使用singleton定义的Bean将只有一个实例,这是默认的配置。
  • Prototype:原型模式。每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例。
  • request:对于每次HTTP请求,使用request定义的Bean都将产生一个新的实例,即每次HTTP请求都会产生不同的Bean实例。当然只有在WEB应用中使用Spring时,该作用域才真正有效。
  • session:对于每次HTTPSession,使用session定义的Bean都将产生一个新的实例时,即每次HTTP Session都将产生不同的Bean实例。同HTTP一样,只有在WEB应用才会有效。
  • global session:每个全局的HTTPSession对应一个Bean实例。仅在portlet Context的时候才有效。

比较常用的singleton和prototype。如果一个Bean实例被设置为singleton,那么每次请求该Bean时都会获得相同的实例。容器负责跟踪Bean实例的状态,负责维护Bean实例的生命周期行为。如果一个Bean实例被设置为prototype,那么每次请求该di的Bean,Spring都会创建一个新的Bean实例返回给程序,在这种情况下,Spring容器仅仅使用new关键字创建Bean实例,一旦创建成功,容器将不会再跟踪实例,也不会维护Bean实例的状态。

如果我们不指定Bean的作用域,则Spring会默认使用singleton作用域。设置Bean的作用域是通过scope属性来指定。可以接受Singleton、prototype、request、session、global session 5个值。

三、Spring中Bean的管理问题

首先,配置文件中定义的bean并不是都在启动时实例化。
< bean id=“accountService” class=“com.foo.DefaultAccountService” scope=“singleton”/>
注意bean有一个属性scope,只有在scope没有配置或配置为如上时,启动时才实例化。(如果一个singleton的bean依赖一个prototype的bean,那么这个prototype的bean在singleton的bean实例化时也会实例化。
如果定义为scope="prototype"那么只有在这个bean被使用时,才实例化,而且每次都是一个新对象,多例。

其次,在配置文件中声明bean使得spring可以管理这些bean,比如声明式事物功能,就需要你的bean在配置文件中配置。在实例化时spring会为你声明的bean生成一个代理对象,代理对象在调用bean的方法前后加上事务控制逻辑。
备注:spring管理bean这样在bean初始化过程中,spring可以做很多事情,比如你写一个pojo,spring通过配置就能让他成为rmi,就是在实例化过程,对这个pojo做了更多的处理,不只是简单的new一个对象出来。
在比如只有spring管理的bean才支持spring的AOP机制。可以使用Aspectj和spring集成,对非spring管理的bean施加AOP

再次,减少代码中依赖耦合。
同样的在配置文件中我们可以ref另外一个bean,这样做又是为什么呢?(我们同样可以使用时new一个这个实例)
回答:
把依赖关系定义在配置文件中。
不要再代码中表现依赖关系,这样在依赖关系有变化的情况下,可以通过配置文件的修改达到目的,而不需要修改代码。

猜你喜欢

转载自blog.csdn.net/csdnlijingran/article/details/83184043
今日推荐