Spring学习(六)-Bean作用域与基于注解的配置

Bean作用域

在配置文件中定义Bean时,用户不但可以配置Bean的属性值以及相互之间的依赖关系,还可以定义Bean的作用域。作用域将对Bean的生命周期和创建方式产生影响。Spring一般采用scope=“作用域类型”的方式。

Bean作用域类型:

  • singleton:在SpringIoC容器中仅存在一个Bean实例,Bean以单实例的方式存在。
  • prototype:每次从容器中调用Bean时,都会返回一个新的实例,即每次调用getBean()方法时,相当于执行了new Bean的操作。
  • request:每次HTTP请求都会创建一个新的Bean。该作用域仅适用于WebApplicationContext环境。
  • session:同一个HTTP Session共享一个Bean,不同HTTP Session使用不同的Bean。该作用域仅适用于WebApplicationContext环境。
  • globalSession:同一个全局Session共享一个Bean,一般用于Portlet应用环境。该作用域仅适用于WebApplicationContext环境。

singleton作用域

Spirng以容器的方式提供了单实例模式功能,任何POJO无须编写特殊的代码,仅通过配置就可以进行单实例模式。
一般情况下,无状态或者状态不可变的类适合使用单实例模式,不过Spring对此实现了一定的提升。在传统开发中,由于Dao类持有Connection这个非线程安全的变量往往没有采用单实例模式。而在Spring环境下,对于所有的Dao类都可以采用单实例模式,因为Spring利用AOP和LocalThread的功能对非线程安全(或称状态)的变量进行了特殊的处理,使这些非线程安全的类变为线程安全的类。
在默认情况下,Spring的ApplicationContext容器在启动时,自动实例化所有singleton的Bean并缓存在容器中。这样做的好处是,首先对Bean提前实例化可以及早发现配置问题,其次Bean以缓存的方式保存,当运行期用到该Bean的时候就无须再实例化,加快了运行效率。如果用户不希望容器在启动时提前实例化singleton的Bean,可以通过lazy-init属性(懒加载)进行控制。

prototype作用域

采用scope=“prototype”指定非单实例作用域的Bean,请看下面的配置:





通过上述配置,boss1、boss2、boss3所引用了都是一个新的实例,每次通过容器的getBean(“car”)方法返回的也是一个新的Car实例。
在默认情况下,Spring容器启动时不实例化prototype的Bean。此外,Spring容器的prototype的Bean交给调用者后,就不再管理Bean的生命周期了。

request作用域

request作用域的Bean对应一个HTTP请求和生命周期,每次HTTP请求调用到Bean时,Spring都会创建一个新的Bean,直到请求处理完毕才销毁这个Bean。

session作用域

Bean的作用域横跨整个HTTP Session,Session中所有HTTP请求共享一个Bean,当会话结束后,实例才被销毁

globalSession作用域

globalSession作用域类似于session作用域,不过仅在Portlet的Web应用中使用。如果不在Portlet应用环境下,globalSession自然就等价于session作用域了。

基于注解的配置

Spring容器启动成功的三个条件为:Bean定义信息、Bean实现类以及Spring本身。如果采用基于XML的配置,Bean定义信息和Bean实现类本身是分离的,而采用基于注解的配置方式时,Bean定义信息即通过在Bean实现类上标注注解实现。

@Component("car")
public class Car{
	.........
}

@Component注解在Car类声明处对类进行标注,它可以被Spirng容器识别,Spring容器自动将POJO转换为容器管理的Bean。
它与以下XML的配置是等效的:


除了@Component以外,Spring提供了三个功能基本和@Component等效的注解,它们分别用于对DAO、Service以及Web层的Controller进行注解,所以这些注解也称为Bean的衍型注解:

  • @Repository:用于对DAO实现类进行注解。
  • @Service:用于对Service实现类进行注解。
  • @Controller:用于对Controller实现类进行注解。

之所以要在@Component之外提供这三种特殊的注解,是为了让注解类本身的用途更加清晰化,此外Spring还赋予它们一些特殊的功能。

自动装配Bean

使用@Autowired进行自动注入

.....
@Service  //将UserServer标注为一个服务层的Bean
public class UserService {
	@Autowired
	private UserDao userDao;
	@Autowired
	private LoginLogDao loginLogDao;
	.....
}

通过使用@Service将UserServer标注为一个服务层的Bean,通过@Autowired注入UserDao和LoginLogDao的Bean。@Autowired默认按类型匹配的方式,在容器查找匹配的Bean,当且仅当一个匹配的Bean时,Spring将其注入到@Autowired标注的变量中。

使用@Qualifier指定注入Bean的名称

如果容器中有一个以上匹配的Bean时,则可以通过@Qualifier注解限定Bean的名称。假如容器中有两个类型为UserDao的Bean,一个名为userDao,另一个名为otherUserDao,则可通过@Qualifier(“userDao”)注入。

.....
@Service  //将UserServer标注为一个服务层的Bean
public class UserService {
	
	@Autowired
	@Qualifier("userDao")
	private UserDao userDao;
	@Autowired
	private LoginLogDao loginLogDao;
	.....
}

如果一个方法拥有多个入参,在默认情况下,Spring自动选择匹配入参类型的Bean进行注入。Spring允许对方法入参标注@Qualifier以指定注入Bean的名称。

@Autowired
public void init(@Qualifier("userDao")UserDao userDao, LogDao logDao){
	this.userDao = userDao;
	this.logDao=logDao;
}

以上例子中,UserDao的入参注入名为userDao的Bean,而LogDao的入参注入LogDao类型的Bean。

你可能感兴趣的:(Spring学习(六)-Bean作用域与基于注解的配置)