全文总结
基于XML配置
1、学习了bean标签,
2、三种配置bean的方式:
1、静态工厂;
2、实例工厂和
3、自定义实现factorybean
1 SpringBean 的配置类

inin-method 与构造方法不同,构造方法是创建对象的,等对象创建以后使用inin-method方法对对象进行初始化。
1.1 bean 标签学习
bean的id 与class

此时产生的bean对象会被存储到beanFactory的singletonObjects中,beanName为"userDao",值为UserDaoImpl对象。可以根据beanName获取Bean实例
context.getBean("userSerice");
如果不配置id,则spring会把bean实例的全限定名作为beanName
context.getBean("cn.msf.dao.impl.UserDaoImpl");
bean的name 起别名
实际中使用较少。

主要是因为在beanFactory中有一个属性为aliasMap。可以将别名与beanName联系在一起,由于是一个map因此别名不能重复,否则会被覆盖。
Bean的范围配置
默认情况下,单纯的Spring环境Bean的作用范围有两个: Singleton和Prototypesinaleton
singleton单例,默认值,Spring容器创建的时候,就会进行Bean的实例化,并存储到容器内部的单例池中每次getBean时都是从单例池中获取相同的Bean实例;
prototype: 原型,Spring容器初始化时不会创建Bean实例,当调用getBean时才会实例化Bean,每次getBean都会创建一个新的Bean实例。
在原型中不会存入单例池中,因此每次getBean时产生一个新对象。

Bean的延时加载
当lazy-init设置为true时为延迟加载,也就是当Spring容器创建的时候,不会立即创建Bean实例,等待用到时在创建Bean实例并存储到单例池中去,后续在使用该Bean直接从单例池获取即可,本质上该Bean还是单例的。

Bean的初始化和销毁方法配置
Bean在被实例化后,可以执行指定的初始化方法完成一些初始化的操作,Bean在销毁之前也可以执行指定的销毁方法完成一些操作,初始化方法名称和销毁方法名称通过

这些方法都是在bean实例化以后(构造方法先执行),因此是该实例自己的方法。设置初始化和销毁的方法名称即可调用。销毁方法,当容器显示关闭时即可自动调用。
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserSerice userSerice = (UserSerice) context.getBean("userSerice");
context.close();

扩展:除此之外,我们还可以通过实现 nitializingBean 接口,完成一些Bean的初始化操作,如下


结果:afterPropertiesSet方法先于init-method方法执行。
Bean的实例化配置
Spring的实例化方式主要如下两种,也就是说beanFactory创建bean的两种方式,一个是反射,beanFactory内部使用工厂创建bean。
构造方式实例化:底层通过构造方法对Bean进行实例化。
<bean id="userSerice" class="cn.msf.service.impl.UserServiceImpl">
<!--name是 有参构造中的输入,value是具体的值。-->
<constructor-arg name="name" value="张三"></constructor-arg>
<!--name 是impl中的set方法,ref 是bean的id-->
<property name="userDao" ref="userDao"></property>
</bean>
// 增加有参构造
public UserServiceImpl(String name) {
System.out.println("UserServiceImpl通过有参构造实例化。");
}

工厂方式实例化:底层通过调用自定义的工厂方法对Bean进行实例化。
静态工厂方法实例化bean:自定义工厂,创建静态方法,在静态方法内部产生bean
实例工厂方法实例化bean:自定义工厂,创建实例方法,在实例方法内部产生bean
实现factoryBean规范延迟实例化Bean
作用:在bean创建对象之前和之后,可以进行其他的逻辑操作;非我自定义的bean也可以用这个。
静态工厂方法实例化bean
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserSerice userSerice = (UserSerice) context.getBean("userSerice");
UserDao userDao1 = (UserDao) context.getBean("userDao1");
System.out.println("userDao1 = " + userDao1);
public class MyFactory1 {
public static UserDao getUserDao(){
return new UserDaoImpl();
}
}
<!--使用静态工厂创建userDao-->
<bean id="userDao1" class="cn.msf.factory.MyFactory1" factory-method="getUserDao"></bean>

实例工厂方法实例化bean

由于是实例工厂,因此先要spring创建工厂对象,在创建后定义工厂对象和工厂方法创建bean对象。

实现factoryBean规范延迟实例化Bean
// 测试代码
UserDao userDao3 = (UserDao) context.getBean("userDao3");
System.out.println("userDao3 = " + userDao3);
public class MyFactory3 implements FactoryBean<UserDao> {
@Override
public UserDao getObject() throws Exception {
return new UserDaoImpl();
}
@Override
public Class<?> getObjectType() {
return UserDao.class;
}
}
<!--使用自定义-->
<bean id="userDao3" class="cn.msf.factory.MyFactory3"></bean>
结果,userDao3缓存在factoryBeanObjectsCache,也是延迟加载
