前言

本文我们来学习spring里面的bean的相关属性,包括作用范围,生命周期,以及bean的一些常用的标签,注解等等。

Scope(Bean的作用范围)

示例配置:

1
2
3
<bean id="accountDao" class="com.lagou.edu.dao.impl.JdbcTemplateDaoImpl"
scope="singleton"
<bean/>

默认值:singleton,可在配置文件中修改。

singleton

单例模式 容器的生命周期内只创建一次

prototype

原型(多例)模式 每次获取bean的时候都是新的对象,也就是每次调用getBean()方法时获取到的都是新的对象。

不同作用范围的生命周期

单例模式:singleton

对象出⽣:当创建容器时,对象就被创建了。 对象活着:只要容器在,对象⼀直活着。 对象死亡:当销毁容器时,对象就被销毁了。 ⼀句话总结:单例模式的bean对象⽣命周期与容器相同。

多例模式:prototype

对象出⽣:当使⽤对象时,创建新的对象实例。 对象活着:只要对象在使⽤中,就⼀直活着。 对象死亡:当对象⻓时间不⽤时,被java的垃圾回收器回收了。 ⼀句话总结:多例模式的bean对象,spring框架只负责创建,不负责销毁。

Bean标签属性

在基于xml的IoC配置中,bean标签是最基础的标签。它表示了IoC容器中的⼀个对象。换句话 说,如果⼀个对象想让spring管理,在XML的配置中都需要使⽤此标签配置,Bean标签的属性如 下:

  • id属性: ⽤于给bean提供⼀个唯⼀标识。在⼀个标签内部,标识必须唯⼀。

  • class属性:⽤于指定创建Bean对象的全限定类名。

  • name属性:⽤于给bean提供⼀个或多个名称。多个名称⽤空格分隔。

  • factory-bean属性:⽤于指定创建当前bean对象的⼯⼚bean的唯⼀标识。当指定了此属性之后,class属性失效。

  • factory-method属性:⽤于指定创建当前bean对象的⼯⼚⽅法,如配合factory-bean属性使⽤,则class属性失效。如配合class属性使⽤,则⽅法必须是static的。

  • scope属性:⽤于指定bean对象的作⽤范围。通常情况下就是singleton。当要⽤到多例模式时,可以配置为prototype。

  • init-method属性:⽤于指定bean对象的初始化⽅法,此⽅法会在bean对象装配后调⽤。必须是⼀个⽆参⽅法。

  • destory-method属性:⽤于指定bean对象的销毁⽅法,此⽅法会在bean对象销毁前执⾏。它只能为scope是singleton时起作⽤。

示例:

1
2
<bean id="accountDao" class="com.lagou.edu.dao.impl.JdbcTemplateDaoImpl" 
scope="singleton" init-method="init" destroy-method="destory">
1
2
3
4
5
6
7
8
9
 public class JdbcAccountDaoImpl implements AccountDao {
public void init() {
System.out.println("初始化方法.....");
}

public void destory(){
System.out.println("销毁方法.....");
}
}

测试:

1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void testIoC() throws Exception {

// 通过读取classpath下的xml文件来启动容器(xml模式SE应用下推荐)
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

AccountDao accountDao = (AccountDao) applicationContext.getBean("accountDao");
applicationContext.close();

}

}

常用的注解形式

xml中对应的注解形式如下图:

依赖注入的实现注解:

@Autowired(推荐使用)

@Autowired为Spring提供的注解,需要导⼊包 org.springframework.beans.factory.annotation.Autowired。 @Autowired采取的策略为按照类型注⼊。

1
2
3
4
public class TransferServiceImpl {
@Autowired
private AccountDao accountDao;
}

如上代码所示,这样装配回去spring容器中找到类型为AccountDao的类,然后将其注⼊进来。这样会产⽣⼀个问题,当⼀个类型有多个bean值的时候,会造成⽆法选择具体注⼊哪⼀个的情况,这个时候我们需要配合着Qualifier使⽤。 @Qualifier告诉Spring具体去装配哪个对象。

1
2
3
4
5
public class TransferServiceImpl {
@Autowired
@Qualifier(name="jdbcAccountDaoImpl")
private AccountDao accountDao;
}

这个时候我们就可以通过类型和名称定位到我们想注⼊的对象

@Resource

@Resource 注解由 J2EE 提供,需要导⼊包 javax.annotation.Resource。 @Resource 默认按照 ByName ⾃动注⼊。

1
2
3
4
5
6
7
8
9
10
public class TransferService {
@Resource
private AccountDao accountDao;
@Resource(name="studentDao")
private StudentDao studentDao;
@Resource(type="TeacherDao")
private TeacherDao teacherDao;
@Resource(name="manDao",type="ManDao")
private ManDao manDao;
}

如果同时指定了 name 和 type,则从Spring上下⽂中找到唯⼀匹配的bean进⾏装配,找不到则抛出异常;

如果指定了name,则从上下⽂中查找名称(id)匹配的bean进行装配,找不到则抛出异常;

如果指定了type,则从上下⽂中找到类似匹配的唯⼀bean进行装配,找不到或是找到多个,都会抛出异常;

如果既没有指定name,⼜没有指定type,则⾃动按照byName方式进行装配 。

注意: @Resource 在 Jdk 11中已经移除,如果要使⽤,需要单独引⼊jar包:

1
2
3
4
5
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency

其他常用注解

还有一些常用的注解,取代xml的内容:

@Configuration 注解,表名当前类是⼀个配置类;

@ComponentScan 注解,替代 context:component-scan;

@PropertySource,引⼊外部属性配置⽂件;

@Import 引⼊其他配置类;

@Value 对变量赋值,可以直接赋值,也可以使⽤ ${} 读取资源配置⽂件中的信息;

@Bean 将⽅法返回对象加入SpringIOC 容器。

总结

我们主要学习了spring里面bean的相关属性,包括作用范围(主要是单例和多例)、生命周期,以及bean的一些常用的标签,经常使用的几个注解(比如@Autowired)等等。