bean的作用域与生命周期 还有自动装配 以及外部文件注入

4.bean的作用域和生命周期
1.作用域

以上列的book 类为例

xml

<!--提取公共bean-->
   <util:list id="bookList">
      <value>sd</value>
      <value>dddd</value>
   </util:list>
   <bean id="book" class="com.xyq.spring_1.TestDemo.collectionBean.Book">
      <property name="list" ref="bookList"></property>
   </bean>

我们要验证默认bean是否为单例

测试类

@Test
public void test01(){

    ApplicationContext context =new ClassPathXmlApplicationContext("bean2.xml");

    Book book1 = context.getBean("book", Book.class);
    Book book2 = context.getBean("book", Book.class);

    System.out.println(book1.hashCode());
    System.out.println(book2.hashCode());

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VMSZ9Nlr-1606220500498)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201122142257908.png)]

由于我们重写了tostring,我们这边就用默认的hashcode方法来比较

我们可以看出是一样的。

所以在默认情况下 bean是单实例的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pIRxkoGj-1606220500502)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201122142454551.png)]

在xml后面添加scope属性,可以看出一个是原型,一个是单例

那么我们选择单例

所以xml代码如下

<!--提取公共bean-->
<util:list id="bookList">
   <value>sd</value>
   <value>dddd</value>
</util:list>
<bean id="book" class="com.xyq.spring_1.TestDemo.collectionBean.Book" scope="prototype">
   <property name="list" ref="bookList"></property>
</bean>

我们再进行输出

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8S99PD95-1606220500504)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201122142610375.png)]

我们可以发现这次就不一样了

下面是 singleton 和 prototype的区别

  1. 一个是单例一个是多实例

  2. 设置scope=singleton 和不设置的时候默认是singleton 那么spring 就会在读取xml即

    ApplicationContext context =new ClassPathXmlApplicationContext(“bean2.xml”);这一行时就创建对象

    即加载的时候就会创建对象

    prototype 就会在 加载的时候不创建,在getbean的时候创建。(即类似懒汉)

所以我们复习一下上面IOC的两大接口

​ 1.BeanFactory:基本接口 spring内部开发者使用 ,懒加载,用的时候才加载

​ 2.ApplicationContext:饿汉式加载,给应用开发者用的,是BeanFactory的子接口

我们再上面写了这么一段,我们在这边可以发现,饿汉式加载,是指加载singleton bean ,其他的bean也是懒加载

此外还有request 和seesion关键字 ,但是这两个一般不用,这是指创建后放在对应的域中

2.生命周期

生命周期分为5步

  1. 创建这个bean的实例(调用bean的无参构造器)

  2. 设置bean的属性(调用set方法)

  3. 调用bean的init-method(初始化)方法 (需要手动配置)

  4. 获取到了可用的bean,开始发挥bean的作用

  5. 在关闭spring容器时,会调用所配置的destroy方法 来销毁 bean实例

    我们开始演示

    第一步 有下面的order类

    public class order {
        private String oName;
    
        public order() {
            System.out.println("第一步 调用构造方法创建bean实例");
        }
    
        public void setoName(String oName) {
            this.oName = oName;
            System.out.println("第二步 调用set 方法设置bean的属性");
        }
    
        public void initMethod(){
            System.out.println("第三步  调用我们在xml配置的初始化方法");
        }
    
        @Override
        public String toString() {
            return "第四步 获取得到了可用的bean"+"order{" +
                    "oName='" + oName + '\'' +
                    '}';
        }
        public void destoryMethod(){
            System.out.println("第五步  关闭容器时, 会调用我们再xml配置好的方法来销毁bean");
        }
    
    }
    

    配置xml文件

    <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"
           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       ">
    
       <!--工厂类-->
    
       <bean id="order" class="com.xyq.spring_1.TestDemo.Bean.order"
       init-method="initMethod" destroy-method="destoryMethod">
          <property name="oName" value="手机"></property>
       </bean>
    
    
    </beans>
    

测试类

@Test
public void showBeanLife(){

    ApplicationContext context =new ClassPathXmlApplicationContext("bean4.xml");
    order order = context.getBean("order", com.xyq.spring_1.TestDemo.Bean.order.class);
    System.out.println(order);
    ((ClassPathXmlApplicationContext) context).close();
}

结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aw7eH68p-1606220500506)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201122150151303.png)]

3.bean的后置处理器

在第三步,调用初始化方法前后,各有一个处理器

这样算下来就有7步

第一步 调用构造方法创建bean实例
第二步 调用set 方法设置bean的属性
初始化之前,将bean传递到了后置处理器的postProcessBeforeInitialization方法处理,然后返回

第三步 调用我们在xml配置的初始化方法

初始化之后,将bean传递到了后置处理器的postProcessAfterInitialization方法处理,然后返回

第四步 获取得到了可用的beanorder{oName=‘手机’}
第五步 关闭容器时, 会调用我们再xml配置好的方法来销毁bean

接下来是演示部分, 类我们还是用order,但是我们要创建一个实现BeanPostProcessor接口的处理器类并将

其塞到容器里面发挥作用

下面是这个类的代码 它叫dealPostBean

public class dealPostBean implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

        System.out.println("初始化之前,将bean传递到了后置处理器的postProcessBeforeInitialization方法处理,然后返回");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        System.out.println("初始化之后,将bean传递到了后置处理器的postProcessAfterInitialization方法处理,然后返回");

        return bean;
    }

}

xml文件

<bean id="order" class="com.xyq.spring_1.TestDemo.Bean.order"
init-method="initMethod" destroy-method="destoryMethod">
   <property name="oName" value="手机"></property>
</bean>

<bean id="dealBean" class="com.xyq.spring_1.TestDemo.Bean.dealPostBean"></bean>

测试类

@Test
public void showBeanLife(){

    ApplicationContext context =new ClassPathXmlApplicationContext("bean4.xml");
    order order = context.getBean("order", com.xyq.spring_1.TestDemo.Bean.order.class);
    System.out.println(order);

    ((ClassPathXmlApplicationContext) context).close();
}
5.自动装配

测试类:

@Test
public void showAutoWrie(){

    ApplicationContext context =new ClassPathXmlApplicationContext("bean5.xml");
    Emp emp = context.getBean("emp", Emp.class);
    System.out.println(emp);
}

xml文件

<bean id="emp" class="com.xyq.spring_1.TestDemo.autowrie.Emp" autowire="byName">
</bean>

<bean id="dept" class="com.xyq.spring_1.TestDemo.autowrie.Dept"></bean>

类使用之前的emp和dept

效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KTum34pQ-1606220500509)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201122155324803.png)]

这边可以看到,对比之前的对象注入我们不再需要使用property标签,直接使用aotowire高效快捷

并且可以注意的是,autowire有 分 byname 和bytype

byname就是按照属性名称找id的

bytype 就是按照属性的类型找值 ,那么就产生一个问题了,就是同个类型用bytype就意味着你不能声明多个同样类型的bean

6.外部文件属性注入

xml

1.引入 xmlns:context=“http://www.springframework.org/schema/context” 和 http://www.springframework.org/schema/context http://www.springframework.org/schema/util/spring-context.xsd在声明头

2.使用<context:property-placeholder

3配置 数据库bean 并设置值。值可以是字面量也可以是${}外部文件的值

<?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/util/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>

</bean>

</beans>

jdbc.properties

prop.driverClass=com.mysql.jdbc.Driver
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值