Spring-02 关于bean的作用域,生命周期,基于注解的注入,生成实例,半自动注解装配以及自动注解

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);
    }

猜你喜欢

转载自blog.csdn.net/qq_41520945/article/details/109189839