•
bean实例化的三种方式
a. 第一种方式:是用无参构造创建
但如果你的类中已经声明了有参构造,那么就不会执行无参构造函数,没有无参构造就去运行会出现异常。额,例如以下这种。
• 第二种方法:使用静态工厂创建
创建一个工厂类,工厂类中返回实体对象的方法是静态的
i. 在配置文件中配置工厂类的id和class,重要的是加上获取对象的方法名factory-method;
ii.
Iii. 创建对象的工厂类
创建对象并执行方法
iii. 第三种方式:使用实例工厂进行创建(也就是返回对象的方法是非静态的)
i. 在配置文件中配置工厂类
ii.
iii. 工厂类编写
- 测试一下能否成功创建对象
• - 调用方法后的运行结果
• - 这种方式创建对象较为麻烦,不常用,但要知道这种方式。
• 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 测试代码:
输出结果是:小米在学习。
• 注入对象的属性(重点)
- 创建service类和dao 类
- 在service中添加dao对象
- 生成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容器的销毁方法,若是多实例就不会有销毁方法执行。
无论是否有初始化方法,后置处理的两个方法都会执行。