Spring bean管理

bean实例化的三种方式

a. 第一种方式:是用无参构造创建
在这里插入图片描述
但如果你的类中已经声明了有参构造,那么就不会执行无参构造函数,没有无参构造就去运行会出现异常。额,例如以下这种。
在这里插入图片描述
• 第二种方法:使用静态工厂创建
创建一个工厂类,工厂类中返回实体对象的方法是静态的
i. 在配置文件中配置工厂类的id和class,重要的是加上获取对象的方法名factory-method;
ii.
在这里插入图片描述
Iii. 创建对象的工厂类

在这里插入图片描述
创建对象并执行方法

在这里插入图片描述

在这里插入图片描述

iii. 第三种方式:使用实例工厂进行创建(也就是返回对象的方法是非静态的)
i. 在配置文件中配置工厂类
ii. 在这里插入图片描述
iii. 工厂类编写

  1. 在这里插入图片描述
  2. 测试一下能否成功创建对象
    在这里插入图片描述
  3. 调用方法后的运行结果
    在这里插入图片描述
  4. 这种方式创建对象较为麻烦,不常用,但要知道这种方式。

• bean标签常用属性

  • id 属性:spring根据id找到xml中对象的具体属性例如classpath,它可以被任意命名但是不能包含特殊的字符,例如:/*&_等。

  •  class属性:创建对象类的全路径;
    
  • name属性:功能和id属性一致,但是他与id不同的是,name的命名可以包含特殊符号。

  •  scope属性:它有5个相对应的值 。
    
  •  prototype:创建对象是多实例的,也就是返回的对象每个都是不一样的
    
  •  singleton:创建的对象是单例的,连续创建对象返回的地址一样 	 request: 在web中创建对象并存入request域
    
  •   session :在web中创建对象并存入session域 
    
  •   globalSession :在web中创建对象存入全局域
    
    • scope="singleton"是指创建的对象是单例的,对象在IOC容器之前就已经创建了, scope="prototype"是多实例的;当使用对象的时候才创建
    • lazy-init属性只对singleton起作用,它默认是false,当想要对象使用的时候才创建就设置成true
    • Init-method属性:如果我们想要对象创建后,执行某个方法我们就把这个方法名当做init-method属性的值;
    • destory-method属性:如果想要在IOC容器销毁后执行方法,就把这个方法作为destory-method的属性值。

• 属性注入方式介绍

  • 什么是注入:就是当创建对象时,给对象添加属性,也就是给对象的属性赋值 Spring注入属性方法(有参构造和set方法)
    set方法注入(重点)

bean对象:
在这里插入图片描述
o applicationContext.xml
o 在这里插入图片描述
o 测试代码:
在这里插入图片描述
输出结果是:小米在学习。

注入对象的属性(重点)

  1. 创建service类和dao 类
  2. 在service中添加dao对象
  3. 生成dao类型属性的set方法
    o 参数是对象时配置文件
    在这里插入图片描述

o service类
o 在这里插入图片描述
o userDao类
在这里插入图片描述
o 输出:add user.
o 有参构造函数注入
 设置有参构造函数
在这里插入图片描述
 配置spring
在这里插入图片描述
 测试一下
在这里插入图片描述
 输出结果
在这里插入图片描述
• p名称空间注入
在这里插入图片描述
• 输出:信息在学习。
• spring注入复杂数据(list,map,properties,数组,)

在这里插入图片描述
集合类型参数注入

<bean id="students" class="main.java.domain.Student">
 
<!--数组-->
<property name="array">
<list>
<value>12</value>
<value>13</value>
<value>14</value>
<value>15</value>
</list>
</property>
 
<!--List-->
<property name="list">
<list>
<value>小武</value>
<value>小两</value>
<value>小生</value>
<value>小八</value>
</list>
</property>
 
<!--map-->
<propertyname="map">
<map>
<entry key="1" value="xxx"></entry>
<entry key="2" value="zzz"></entry>
<entry key="3" value="ccc"></entry>
<entry key="5" value="rrr"></entry>
</map>
</property>
 
<!--properties-->
<property name="properties">
<props>
<prop key="driverClass">com.mysql.jdbc.driver</prop>
<prop key="username">root</prop>
<prop key="password">root</prop>
</props>
</property>
 
</bean>

测试方法;
在这里插入图片描述
输出结果:

在这里插入图片描述
IOC容器中注册的bean;

  • 单实例bean,容器启动的时候就会创建好,容器关闭的时候也会销毁
  • 多实例的bean,获取的时候才创建;

我们可以为bean自定义一些生命周期的方法,spring在创建或销毁的时候就会调用指定方法,init-method="";destory-method="";这两个方法是当IOC容器启动的时候和关闭的时候才会执行。并且他们不能设置参数。

public void carInit()
{
    System.out.println("ioc初始化完成....");
}


public void carDestroy()
{
    System.out.println("ioc容器销毁......");
}

配置信息:指定正确的初始化方法和销毁方法。

<bean id="Car02" class="main.java.domain.Car" init-method="carInit" destroy-method="carDestroy"></bean>

测试:

void test05(){

}

代码块中没有任何内容,但是测试结果是:

Car 被创建...
ioc初始化完成....

这时加入以下代码:

void test05()
{
    Object car02 = context.getBean("Car02");
    System.out.println("test05....");
    context.close();
}
输出结果为:
 Car 被创建...
ioc初始化完成....

test05....
ioc容器销毁......

所以,单实例的bean的生命周期:构造函数->IOC初始化方法->方法体中执行的代码->IOC销毁方法

再来看多实例的bean:
将**scope=“prototype”**然后,

@Test
void test06()
{
    System.out.println("test06....");
    context.close();
}
输出结果是: test06...

因为多实例必须在获得对象的时候才创建,所以这样做是不会调用构造方法的。并且通过上面的测试可以看出IOC容器关闭也不会调用销毁方法。当我们获得对象后在执行。

void test06()
{
    Object car02 = context.getBean("Car02");
    System.out.println("test06....");
    context.close();
}

输出结果为:
Car 被创建...
ioc初始化完成....
test06....

所以得出多实例bean的生命周期:获取bean时才执行构造方法和初始化方法-当容器关闭不会调用destory方法。

后置处理器接口:BeanPostProcess;他有两个方法一个在IOC初始化之前执行,另一个在IOC初始化之后执行。
创建一个类实现BeanPostProcess接口;进行测试;

package main.java.factory;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;


public class MyBeanPostProcess implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
        System.out.println("初始化之前的方法执行了。。。");
        return o;
    }

    @Override
    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
        System.out.println("初始化后的方法执行了。。。");
        return o;
    }
}

配置这个类。

<bean class="main.java.factory.MyBeanPostProcess" scope="singleton" id="beanPostProcess" ></bean>

还是执行test06输出结果是:

Car 被创建…
初始化之前的方法执行了。。。
ioc初始化完成…
初始化后的方法执行了。。。
test06…

所以最先执行的是构造函数->后置处理before方法->配置有IOC初始化的方法->后置处理after方法->测试方法的输出->最后如果是单例就会有IOC容器的销毁方法,若是多实例就不会有销毁方法执行。
无论是否有初始化方法,后置处理的两个方法都会执行。

原文地址:https://www.cnblogs.com/dataoblogs/p/14121989.html