• Spring学习(三)-Bean的种类,作用域,生命周期


    一、Bean的种类

    1.1、种类介绍

    Spring 中有两种类型的 Bean, 一种是普通Bean, 另一种是工厂Bean, 即FactoryBean.

    工厂 Bean 跟普通Bean不同, 其返回的对象不是指定类的一个实例, 其返回的是该工厂 Bean 的 getObject 方法所返回的对象

    1)普通 bean:在配置文件中定义 bean 类型就是返回类型

    2)工厂 bean:在配置文件定义 bean 类型可以和返回类型不一样

    image

    1.2、FactoryBean实现

    1)创建类,让这个类作为工厂 bean,实现接口 FactoryBean

    package com.dianchou.spring.bean;
    
    import com.dianchou.spring.dao.Course;
    import org.springframework.beans.factory.FactoryBean;
    
    /**
     * @author lawrence
     * @create 2020-07-07 16:29
     */
    public class MyBean implements FactoryBean<Course> {
    
        //定义返回 bean
        @Override
        public Course getObject() throws Exception {
            Course course = new Course();
            course.setName("Math");
            return course;
        }
    
        @Override
        public Class<?> getObjectType() {
            return null;
        }
    
        @Override
        public boolean isSingleton() {
            return false;
        }
    }
    
    

    2)spring配置文件配置

    <bean id="myBean" class="com.dianchou.spring.bean.MyBean"></bean>

    3)测试

    @Test
    public void testMyBean(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("bean3.xml");
        Course course = ctx.getBean("myBean", Course.class);
        System.out.println(course);
    }
    image

    二、Bean作用域

    1)在 Spring 中, 可以在 <bean> 元素的 scope 属性里设置 Bean 的作用域.

    2)默认情况下, Spring 只为每个在 IOC 容器里声明的 Bean 创建唯一一个实例, 整个 IOC 容器范围内都能共享该实例:所有后续的 getBean() 调用和 Bean 引用都将返回这个唯一的 Bean 实例.该作用域被称为 singleton, 它是所有 Bean 的默认作用域

    image

    3)singleton 和 prototype 区别

    ①singleton 单实例,prototype 多实例

    ②设置 scope 值是 singleton 时候,加载 spring 配置文件时候就会创建单实例对象 ;设置 scope 值是 prototype 时候,不是在加载 spring 配置文件时候创建 对象,在调用 getBean 方法时候创建多实例对象

    三、Bean生命周期

    3.1、生命周期

    从对象创建到对象销毁的过程

    3.2、bean 生命周期

    (1)通过构造器创建 bean 实例(无参数构造)

    (2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)

    (3)调用 bean 的初始化的方法(需要进行配置初始化的方法)

    (4)bean 可以使用了(对象获取到了)

    (5)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)

    3.3、生命周期演示

    1)创建实体类

    package com.dianchou.spring.bean;
    
    /**
     * @author lawrence
     * @create 2020-07-07 17:18
     */
    public class Person {
        private String Name;
    
        public Person() {
            System.out.println("第一步: 执行无参构造器创建Bean对象");
        }
    
        public void setName(String name) {
            Name = name;
            System.out.println("第二步: 调用set方法设置属性值");
        }
    
        public void initMethod(){
            System.out.println("第三步: 执行初始化方法");
        }
    
        public void destroyMethod(){
            System.out.println("第五步: 执行销毁方法");
        }
    }
    

    2)spring配置文件

    <bean id="person" class="com.dianchou.spring.bean.Person" init-method="initMethod" destroy-method="destroyMethod">
        <property name="name" value="lawrence"></property>
    </bean>
    

    3)测试

    @Test
    public void testBean() {
        // ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
        Person person = context.getBean("person", Person.class);
        System.out.println("第四步 获取创建 bean 实例对象");
        System.out.println(person);
        //手动让 bean 实例销毁
        context.close();
    }
    image

    3.4、Bean的后置处理器

    Bean 后置处理器允许在调用初始化方法前后对 Bean 进行额外的处理.

    Bean 后置处理器对 IOC 容器里的所有 Bean 实例逐一处理, 而非单一实例. 其典型应用是: 检查 Bean 属性的正确性或根据特定的标准更改 Bean 的属性.

    对Bean 后置处理器而言, 需要实现接口BeanPostProcessor. 在初始化方法被调用前后, Spring 将把每个 Bean 实例分别传递给上述接口的以下两个方法:

    image

    bean 的后置处理器,bean 生命周期有七步

    (1)通过构造器创建 bean 实例(无参数构造)

    (2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)

    (3)把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization

    (4)调用 bean 的初始化的方法(需要进行配置初始化的方法)

    (5)把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization

    (6)bean 可以使用了(对象获取到了)

    (7)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)

    实例演示:

    1)创建类,实现接口 BeanPostProcessor,创建后置处理器

    package com.dianchou.spring.bean;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    
    /**
     * @author lawrence
     * @create 2020-07-07 17:46
     */
    public class MyBeanPost implements BeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName)
                throws BeansException {
            System.out.println("在初始化之前执行的方法");
            return bean;
        }
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName)
                throws BeansException {
            System.out.println("在初始化之后执行的方法");
            return bean;
        }
    }
    
    

    2)spring配置文件

    <bean id="myBeanPost" class="com.dianchou.spring.bean.MyBeanPost"></bean>
    
    <bean id="person" class="com.dianchou.spring.bean.Person" init-method="initMethod" destroy-method="destroyMethod">
        <property name="name" value="lawrence"></property>
    </bean>
    

    3)测试

    @Test
    public void testBean() {
        // ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
        Person person = context.getBean("person", Person.class);
        System.out.println("第四步 获取创建 bean 实例对象");
        System.out.println(person);
        //手动让 bean 实例销毁
        context.close();
    }

    image

    四、Bean的自动装配

    4.1、什么是自动装配

    根据指定装配规则(属性名称或者属性类型),Spring 自动将匹配的属性值进行注入

    4.2、示例

    1)根据属性名称自动注入

    <!--实现自动装配
     bean 标签属性 autowire,配置自动装配
     autowire 属性常用两个值:
     byName 根据属性名称注入 ,注入值 bean 的 id 值和类属性名称一样
     byType 根据属性类型注入
    -->
    <bean id="emp" class="com.atguigu.spring5.autowire.Emp" autowire="byName">
    
    </bean> <bean id="dept" class="com.atguigu.spring5.autowire.Dept"></bean>

    2)根据属性类型自动注入

    <!--实现自动装配
     bean 标签属性 autowire,配置自动装配
     autowire 属性常用两个值:
     byName 根据属性名称注入 ,注入值 bean 的 id 值和类属性名称一样
     byType 根据属性类型注入
    -->
    <bean id="emp" class="com.atguigu.spring5.autowire.Emp" autowire="byType">
    
    </bean> <bean id="dept" class="com.atguigu.spring5.autowire.Dept"></bean>

    五、外部属性文件引入(如jdbc)

    1)引入相关jar包

    image

    2)创建外部属性文件,properties 格式文件,写数据库信息

    prop.driverClass=com.mysql.jdbc.Driver
    prop.url=jdbc:mysql://localhost:3306/mybatis
    prop.userName=root
    prop.password=123456

    3)把外部 properties 属性文件引入到 spring 配置文件中(需要加入context名称空间)

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:p="http://www.springframework.org/schema/p"
           xmlns:util="http://www.springframework.org/schema/util"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                               http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
                               http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
    
        <!--引入外部资源文件-->
        <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    
        <!--配置连接池-->
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="${prop.driverClass}"></property>
            <property name="url" value="${prop.url}"></property>
            <property name="username" value="${prop.userName}"></property>
            <property name="password" value="${prop.password}"></property>
        </bean>
    </beans>

    4)测试

    @Test
    public void testDataSource() throws SQLException {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
        DruidDataSource dataSource = context.getBean("dataSource", DruidDataSource.class);
        System.out.println(dataSource.getConnection());
        System.out.println(dataSource.getDriverClassName());
    }

    image

  • 相关阅读:
    【topcoder SRM 702 DIV 2 250】TestTaking
    【24.67%】【codeforces 551C】 GukiZ hates Boxes
    【TP SRM 703 div2 500】 GCDGraph
    【TP SRM 703 div2 250】AlternatingString
    【35.02%】【codeforces 734A】Vladik and flights
    Android总结篇系列:Android Service
    java之常用正则表达式
    一种软件定义的固态盘融合存储方法
    MongoDB常用语句
    编程界十大顶级IDE
  • 原文地址:https://www.cnblogs.com/hujinzhong/p/13261567.html
Copyright © 2020-2023  润新知