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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM