Spring-02
1.bean作用域
bean的作用域有7种,最常用的有单例和原型
1.1 singleton 单例
singleton是Spring容器默认的作用域,当Bean的作用域为singleton时,Spring容器就只会存在一个共享的Bean实例。singleton作用域对于无会话状态的Bean(如Dao 组件、Service组件)来说,是最理想的选择。
singleton 1.在容器启动只创建一个 id 为student1 bean 2.并且放置在容器中,容器管理他的生命周期
<!--
声明让容器创建一个 Student类型的bean id student1
scope="singleton" 容器创建bean scope 默认的 作用域是单例singleton
singleton 1.在容器启动只创建一个 id 为student1的 bean 2.并且放置在容器中,容器管理他的生命周期
-->
<bean class="com.yth.entity.Student" id="student1" scope="singleton">
<property name="id" value="100"></property>
<property name="name" value="赵四"></property>
</bean>
测试
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("scope/student.xml");
//关于singleton 单例的测试
@Test
public void Test01(){
Student student = (Student) applicationContext.getBean("student1");
System.out.println(student);
}
1.2 propertype 原型
当用户向容器获取bean 时,容器才创建,容器只负责创建,不负责保存维护他的生命周期
<!--
声明让容器创建bean 作用域prototype
prototype 1.用户向容器获取时 创建id student2对象 2.每次都创建新的对象
3.容器只负责帮我们创建 不会放置在容器中,不会管理bean 的生命周期 ,由用户自己负责
-->
<bean class="com.yth.entity.Student" id="student2" scope="prototype">
<property name="id" value="101"></property>
<property name="name" value="广坤"></property>
</bean>
测试
//关于propertype 原型的测试
@Test
public void Test02(){
Student student1 = (Student) applicationContext.getBean("student2");
System.out.println(student1.hashCode());
Student student2 = (Student) applicationContext.getBean("student2");
System.out.println(student2.hashCode());
}
2.bean的生命周期
bean 的生老病死
单例的bean:随着容器的启动,bean 创建,容器并负责维护bean的生命周期
原型的bean: 容器启动时不创建bean,当用户获取时容器才创建bean,每次都是新的bean,容器部管理他的生命周期
Spring容器可以管理Bean部分作用域的生命周期。有关说明具体如下
- singleton
Spring容器可以管理singleton作用域的Bean的生命周期,在此作用域下,Spring能够精确的知道该Bean何时被创建,何时初始化完成,以及何时被销毁。
- prototype
prototype作用域的Bean,Spring只负责创建,当容器创建了Bean实例后,Bean的实例就交给客户端代码来管理,Spring容器将不再跟踪其生命周期。
示例:
1.在Student增加声明周期相关的方法
/**
* 初始化方法
*/
public void init(){
System.out.println("对象初始化");
}
/**
* 销毁方法
*/
public void destroy(){
System.out.println("对象销毁了");
}
2.创建lifebean.xml,设置对应的方法
<!--
init-method="init" 容器创建bean 时调用 初始化方法
destroy-method="destroy" 当容器销毁时调用 销毁方法
-->
<bean class="com.yth.entity.Student" id="student1" scope="singleton"
init-method="init" destroy-method="destroy">
<property name="id" value="104"></property>
<property name="name" value="赵四"></property>
</bean>
<!--
声明 一个原型的bean 当用户获取时创建,容器只负责创建 不负责bean 的生命周期,由用户自己管理
当容器销毁时 bean 的destroy 不会被容器调用
-->
<bean id="student2" class="com.yth.entity.Student"
scope="prototype" init-method="init" destroy-method="destroy">
<property name="id" value="105"></property>
<property name="name" value="广坤"></property>
</bean>
3.测试
//关于bean的生命周期
@Test
public void Test03(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("life\\lifeBean.xml");
// 向容器获取原型 对象此时 触发原型的创建
Student student1 = (Student) applicationContext.getBean("student1");
// 显示调用容器的销毁方法 销毁前会将容器中所有的bean 先销毁, 调用bean 的destroy()
Student student2 = (Student) applicationContext.getBean("student2");
applicationContext.destroy();
}
3.基于Annotation的装配
基于XML的装配可能会导致XML配置文件过于臃肿,给后续的维护和升级带来一定的困难。为此,Spring提供了对Annotation(注解)技术的全面支持。
3.1 注入的注解
@Autowired:用于对Bean的属性变量、属性的setter方法及构造方法进行标注,配合对应的注解处理器完成Bean的自动配置工作。
@Qualifier:与@Autowired注解配合使用,会将默认的按Bean类型装配修改为按Bean的实例名称装配,Bean的实例名称由@Qualifier注解的参数指定。
@Resource:其作用与Autowired一样。@Resource中有两个重要属性:name和type。Spring将name属性解析为Bean实例名称,type属性解析为Bean实例类型。
// @Autowired // 根据类型进行注入若有,多个类型的实例,需要配合 @Qualifier("studentDaoImpl2")
// @Qualifier("studentDaoImpl2")
@Resource() // 默认按照注解的字段名称进行装配, 若没有找到根据类型装配,如果对应类型的实例有多个需要限定
private StudentDao studentDao ;
3.2 生成实例的注解
@Component:用于描述Spring中的Bean,它是一个泛化的概念,仅仅表示一个组件。
@Repository:用于将数据访问层(DAO)的类标识为Spring中的Bean 。dao对象,时能访问数据库的
@Service:用于将业务层(Service)的类标识为Spring中的Bean。service对象,可以做业务处理,有事务等功能
@Controller:用于将控制层(Controller)的类标识为Spring中的Bean 。控制器对象,可以接受用户提交的参数,显示请求的处理结果。
3.3 半自动注解装配
只能进行注入,使注入的注解生效,bean的生成还需要在xml进行配置
实现是 context:annotation-config</context:annotation-config>
1.首先在容器中声明bean
2.使用对应注入的注解 注入bean
3.是注入的注解生效
<!--
作用就是让 注入的注解生效
-->
<context:annotation-config></context:annotation-config>
<!--1. 声明 bean-->
<bean id="studentDao1" class="com.yth.dao.impl.StudentDaoImpl"></bean>
<bean id="studentDao2" class="com.yth.dao.impl.StudentDaoImpl"></bean>
<bean id="studentService" class="com.yth.service.impl.StudentServiceImpl">
</bean>
public class StudentServiceImpl implements StudentService {
//注入注解 注入bean
@Autowired //去容器中 查找bean,并设置到当前属性中 如果容器有 多个类型的bean则报错
// @Qualifier("studentDao1")// @Qualifier 与@Autowired 配合 ,当根据类型找到多个时 使用 @Qualifier 按照id 或者name 查找为一个bean
// @Resource(name = "studentDao")// 首先按照 id 为属性名studentDao1 去容器中找到对应的bean 2.如果找不到 在按照类型去查找 如果找到多个 报错
private StudentDao studentDao;
public StudentDao getStudentDao() {
return studentDao;
}
public void setStudentDao(StudentDao studentDao) {
this.studentDao = studentDao;
}
public Student findStudentById(int id) {
return studentDao.fingStudentById(id);
}
}
<!--
作用就是让 注入的注解生效
-->
<context:annotation-config></context:annotation-config>
测试
public class Test02 {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("annotation\\ annotation.xml");
//关于半自动注解装配测试
@Test
public void Test01(){
StudentService studentService = applicationContext.getBean(StudentService.class);
Student studentById = studentService.findStudentById(102);
System.out.println(studentById);
}
//增加studentDao 的bean的声明,id不同的测试,再添加一个注解@Qualifier("studentDao1"),获取id为studentDao1的bean
@Test
public void Test02(){
// StudentService studentService = applicationContext.getBean(StudentService.class);
StudentService studentService = (StudentService) applicationContext.getBean("studentService");
Student studentById = studentService.findStudentById(102);
System.out.println(studentById);
}
//@Resource(name = "studentDao1") 使用resource注解
@Test
public void Test03(){
StudentService studentService = (StudentService) applicationContext.getBean("studentService");
Student studentById = studentService.findStudentById(102);
System.out.println(studentById);
}
}
3.4 自动注解
context:component-scan
自动注解就是 通过注解自动的生成bean 并经行装配
实现:在xml 声明 context:component-scan 使对应包下的 注入的注解(@Autowired @Qualifie @Resource )生成bean的注解(@Component@Repository @Service @Controller)生效
实现
1.开启自动注解xml
<!--
开启 自动注解功能 使 注入的注解(@Autowired @Qualifie @Resource )生成bean的注解(@Component@Repository @Service @Controller)生效
-->
<context:component-scan base-package="com.qfedu"></context:component-scan>
2.标记需要 生成 bean 和主要注入的属性
dao
@Repository // 标记当前类是dao层
public class StudentDaoImpl implements StudentDao {
public Student fingStudentById(int id) {
Student student =new Student();
student.setId(102);
student.setName("刘能");
return student;
}
}
service
@Service
public class StudentServiceImpl implements StudentService {
//注入注解 注入bean
@Autowired //去容器中 查找bean,并设置到当前属性中 如果容器有 多个类型的bean则报错
// @Qualifier("studentDao1")// @Qualifier 与@Autowired 配合 ,当根据类型找到多个时 使用 @Qualifier 按照id 或者name 查找为一个bean
// @Resource(name = "studentDao")// 首先按照 id 为属性名studentDao1 去容器中找到对应的bean 2.如果找不到 在按照类型去查找 如果找到多个 报错
private StudentDao studentDao;
public StudentDao getStudentDao() {
return studentDao;
}
public void setStudentDao(StudentDao studentDao) {
this.studentDao = studentDao;
}
public Student findStudentById(int id) {
return studentDao.fingStudentById(id);
}
}
测试
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("autoAnnotation\\autoAnnotation.xml");
//全自动注解的测试
@Test
public void Test01(){
StudentService studentService = (StudentService) applicationContext.getBean(StudentService.class);
Student studentById = studentService.findStudentById(102);
System.out.println(studentById);
}