spring-02


spring-day02

1、bean的上面周期

大体上分为:

  1. 通过构造器创建 bean 实例(无参数构造)
  2. 为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
  3. 调用 bean 的初始化的方法(需要进行配置初始化的方法)
  4. bean 可以使用了(对象获取到了)
  5. 当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)

生命周期的演示:
实体类:

public class Cycle {

    private String time;

    public Cycle() {
        System.out.println("第一步:调用无参构造创建bean的实例");
    }

    public void setTime(String time) {
        this.time = time;

        System.out.println("第二步:为属性设置值");
    }

    /**
     * 初始化bean对象
     */
    public void initMethod(){
        System.out.println("第三步:执行初始化的方法");
    }

    /**
     * 销毁bean对象
     */
    public void destroyMethod(){
        System.out.println("第五步:执行销毁的方法");
    }
}

xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--
        用于测试生命周期
    -->
    <bean class="com.day02.entity.Cycle" id="cycle" init-method="initMethod" destroy-method="destroyMethod">
        <property name="time" value="2021-12-17"></property>
    </bean>
</beans>

测试:

@Test
    public void cycleTest(){
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("bean.xml");

        Cycle cycle = context.getBean("cycle", Cycle.class);
        System.out.println("第四步:获取创建bean的实例对象");


        // 手动让bean实例销毁
        context.close();
    }

结果:

第一步:调用无参构造创建bean的实例
第二步:为属性设置值
第三步:执行初始化的方法
第四步:获取创建bean的实例对象
第五步:执行销毁的方法

如果添加了后置处理器的话,那么生命周期就有七步,另外两步在调用bean的初始化方法的前后。如果我们在xml配置文件中添加了关于创建实现BeanPostProcessor接口的类的bean实例时,那么配置文件中的所有bean实例都会自动识别。

作为后置处理器的类:

public class Mybean 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;
    }
}

实体类:

public class Cycle {

    private String time;

    public Cycle() {
        System.out.println("第一步:调用无参构造创建bean的实例");
    }

    public void setTime(String time) {
        this.time = time;

        System.out.println("第二步:为属性设置值");
    }

    /**
     * 初始化bean对象
     */
    public void initMethod(){
        System.out.println("第三步:执行初始化的方法");
    }

    /**
     * 销毁bean对象
     */
    public void destroyMethod(){
        System.out.println("第五步:执行销毁的方法");
    }
}

xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 用于测试后置处理器 -->
    <bean class="com.day02.entity.Cycle" id="cycle" init-method="initMethod" destroy-method="destroyMethod">
        <property name="time" value="2021-12-17"></property>
    </bean>

    <!-- 用于测试后置处理器,观察配置文件中的所有bean是否都调用了配置处理器的方法-->
    <bean class="com.day02.entity.Processor" id="processor" init-method="initMethod" destroy-method="destroyMethod">
        <property name="otherTime" value="2021-12-17"></property>
    </bean>

    <!-- 用于测试后置处理器,观察配置文件中的所有bean是否都调用了配置处理器的方法-->
    <bean class="com.day02.entity.Cat" scope="prototype" id="cat">
        <property name="catName" value="Jack"></property>
        <property name="weight" value="10.2"></property>
    </bean>

    <!--
        配置后置处理器:因为在MyBean实现了BeanPostProcessor接口,
        此时只要创建bean实例,系统就是识别为后置处理器
            1: 在此配置文件的对象都会调用后置处理器中的
                postProcessBeforeInitialization和postProcessAfterInitialization方法
    -->
    <bean class="com.day02.bean.Mybean" id="mybean"></bean>
</beans>

测试:

@Test
    public void cycleTest(){
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("bean2.xml");

        Cycle cycle = context.getBean("cycle", Cycle.class);
        System.out.println("第四步:获取创建bean的实例对象");

        // 手动让bean实例销毁
        context.close();
    }

结果:

第一步:调用无参构造创建bean的实例
第二步:为属性设置值
初始化前调用
第三步:执行初始化的方法
初始化后调用
第四步:获取创建bean的实例对象
第五步:执行销毁的方法

2、自动装配 autowire

autowire:自动注入

  1. byName:根据属性名称注入(在Emp中属性Dept的名称为dept,这时会识别id为dept的bean实例)
  2. byType:根据类型注入(在Emp中dept属性的类型为Dept,这时就会根据Dept类型进行匹配,如果有多个类型相同的bean实例,那么系统就会提示错误)

这里用前面的部门Dept和员工Emp类作为实体类进行解释:
实体类:

public class Dept {
    private String deptName;

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }

    @Override
    public String toString() {
        return "Dept{" +
                "deptName='" + deptName + '\'' +
                '}';
    }
}


public class Emp {
    private Dept dept;

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "dept=" + dept +
                '}';
    }
}

xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--
        autowire:自动注入
            byName:根据属性名称注入(在Emp中属性Dept的名称为dept,这是会识别id为dept的bean实例)
     -->
    <bean class="com.day02.autowire.Dept" id="dept">
        <property name="deptName" value="研发部"></property>
    </bean>

        <bean class="com.day02.autowire.Dept" id="dept2">
            <property name="deptName" value="产品融资部"></property>
        </bean>

        <!--
            使用byName进行自动装配
        -->
    <bean class="com.day02.autowire.Emp" id="emp" autowire="byName">
        <!--
            <property name="dept" ref="dept"></property>:用自动装配取代
        -->
    </bean>

    <!--
        使用byType进行自动装配:
            在这个配置文件中会提示错误,因为有多个类型为Dept的bean,所以无法识别

    <bean class="com.day02.autowire.Emp" id="emp2" autowire="byType"></bean>
    -->
</beans>

测试:

public class AutoWireTest {
    /**
     * 测试byName
     */
    @Test
    public void byNameTest(){
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean3.xml");
        Emp emp = context.getBean("emp", Emp.class);
        System.out.println(emp);
    }

    /**
     * 测试byType
     */
    @Test
    public void byTypeTest(){
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean3.xml");
        Emp emp = context.getBean("emp2", Emp.class);
        System.out.println(emp);
    }
}

byName的测试结果:

Emp{dept=Dept{deptName='研发部'}}

byType的测试也很简单,就不演示了。

3、外部文件的注入

比如我们注入连接数据库的properties文件
注意:注入外部文件时,要添加context名称空间。
通过<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>导入jdbc.properties文件

<?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: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/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!--
        注入外部文件,需要引入context名称空间
    -->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

    <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
        <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>

写这个文章主要是用于自己对知识点的梳理,当然也有想让各位跟我一样的小白参考,作者学识浅薄,有可能有错误,所以欢迎纠错,一起学习讨论,一起进步。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值