spring中引入外部文件的方法和bean的生命周期

88 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第21天,点击查看活动详情

Spirng管理数据库和引入外部文件
在pom.xml添加依赖
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.3</version>
</dependency>
<!-- 数据源 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.0.31</version>
</dependency>
创建一个jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC&amp;characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456
配置bean 利用context:property-placeholder引入jdbc文件
<!--引入jdbc.properties,之后就可以通过${key}的方式访问value-->
    <context:property-placeholder location="jdbc.properties"></context:property-placeholder>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
     </bean>
</beans>
测试
@Test
public void testDatasource() throws SQLException {
​
    ApplicationContext ioc=new ClassPathXmlApplicationContext("spring-datasource.xml");
    DruidDataSource dataSource = ioc.getBean(DruidDataSource.class);
    System.out.println("dataSource.getConnection() = " + dataSource.getConnection());
}

看是否连接成功

bean的作用域

<!--scope:设置bean的作用域
scope="singleton|prototype"
singleton(单例):表示获取改bean所对应的对象都是同一个
prototype(多例):表示获取该bean所对应的对象都不是同一个
如果是在WebApplicationContext幻境下还会有另外两个作用域(但不常用)
request 在一个请求范围内有效
|session 在一个会话范围内有效-->
​
    <bean id="student" class="com.atguigu.spring.pojo.Student" scope="prototype">
        <property name="sid" value="1001"></property>
        <property name="sname" value="占山"></property>
    </bean>

注意:

  • 若bean的作用域为单例时,生命周期的前三个步骤会在获取IOC容器时执行
  • 若bean的作用域为多例时,生命周期的三个步骤会在回去bean时执行

bean的生命周期

具体的生命周期过程

bean对象创建(调用无参构造器) 给bean对象设置属性 bean对象初始化之前操作(由bean的后置处理器负责) bean对象初始化(需在配置bean时指定初始化方法) bean对象初始化之后操作(由bean的后置处理器负责) bean对象就绪可以使用 bean对象销毁(需在配置bean时指定销毁方法) IOC容器关闭

修改user类

public class User {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    public User() {
        System.out.println("生命周期1:实例化");
    }
    public User(Integer id, String username, String password, Integer age) {
        this.id = id;
        this.username = username;
​
        this.password = password;
        this.age = age;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        System.out.println("生命周期2:依赖注入");
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + ''' +
                ", password='" + password + ''' +
                ", age=" + age +
                '}';
    }
    public void initMethod(){
        System.out.println("生命周期3:初始化");
    }
    public void destroyMethod(){
        System.out.println("生命周期4:销毁");
    }
}

spring-lifecycle的配置bean

<bean id="user"   scope="prototype" class="com.atguigu.spring.pojo.User" init-method="initMethod" destroy-method="destroyMethod">
    <property name="id" value="1"></property>
    <property name="username" value="张三"></property>
    <property name="password" value="123"></property>
    <property name="age" value="15"></property>
</bean>
<bean id="MyBeanPostProcessor"  class="com.atguigu.spring.process.MyBeanPostProcessor"></bean>

将scope设置为多例不会在创建ioc时创建 销毁不由ioc管理

image-20221016194005545.png

/**
 * 1.实例化
 * 2.依赖注入
 * 3.后置处理器的postProcessBeforeInitialization
 *  4.初始化,需要通过bean的init-method属性
 *  5.后置处理的postProcessAfterInitialization
 *  6.IOC容器关闭时销毁 需要通过bean的destroy-method属性指定销毁的方法
 *  注意:
 *  若bean的作用域为单例时,生命周期的前三个步骤会在获取IOC容器时执行
 *  若bean的作用域为多例时,生命周期的三个步骤会在回去bean时执行
* @author zzw
* @version 1.0
* Create by 2022/10/16  19:26
*/
​
    @Test
    public void test(){
        //ConfigurableApplicationContext是ApplicationContext的子接口
        //其中扩展了刷新和关闭容器的方法
//        将scope设置为多例不会在创建ioc时创建 销毁不由ioc管理
        ConfigurableApplicationContext ioc=new ClassPathXmlApplicationContext("spring-lifecycle.xml");
        User user = ioc.getBean(User.class);
        System.out.println(user);
        ioc.close();
    }
后置处理器

bean的后置处理器会在生命周期的初始化前后添加额外的操作,需要实现BeanPostProcessor接口,且配置到IOC容器中,需要注意的是,bean后置处理器不是单独针对某一个bean生效,而是针对IOC容器中所有bean都会执行

image-20221016195356101.png

生命周期的过程中的细节以及多例和单例的区别:

1.实例化

2.依赖注入

3.后置处理器的postProcessBeforeInitialization

4.初始化,需要通过bean的init-method属性

5.后置处理的postProcessAfterInitialization

6.IOC容器关闭时销毁 需要通过bean的destroy-method属性指定销毁的方法

注意:

若bean的作用域为单例时,生命周期的前三个步骤会在获取IOC容器时执行

若bean的作用域为多例时,生命周期的三个步骤会在回去bean时执行

FactoryBean

接口FactoryBean

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package org.springframework.beans.factory;
​
import org.springframework.lang.Nullable;
​
public interface FactoryBean<T> {
    String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
​
    @Nullable
    T getObject() throws Exception;
​
    @Nullable
    Class<?> getObjectType();
​
    default boolean isSingleton() {
        return true;
    }
}
public class UserFactoryBean implements FactoryBean<User> {
    @Override
    public User getObject() throws Exception {
        return new User();
    }
​
    @Override
    public Class<?> getObjectType() {
        return User.class;
    }
}

实现FatoryBean接口

配置FatoryBean

image-20221016203706199.png

@Test
public void testFactoryBean(){
    ApplicationContext ioc =new ClassPathXmlApplicationContext("spring-factory.xml");
    User user = ioc.getBean(User.class);
    System.out.println(user);
}

description:

  • factoryBean是一个接口,需要创建一个类实现该接口
  • 其中有三个方法:
  • getObject():通过一个对象交给IOC容器管理
  • getObjectType():设置所提供对象的类型
  • isSingleton():所提供的对象是否单例
  • 当把FactoryBean的实现类配置为bean时,会将当前类中getObject()所返回的对象那个交给IOC容器管理