1.Bean标签基本配置
用于配置对象交由Spring来创建
默认情况下,它调用的是类中的无参构造函数,如果没有无参构造函数则不能创建成功。无参构造函数调用一次,代表对象创建一次。
基本属性:
id:Bean实例在Spring容器中的唯一标识
class:Bean全限定名称


2.Bean标签的范围配置
scope:指对象的作用范围,取值如下:

刚才的xml文件中其实是配置了scope,只不过是默认的singleton
首先看配置成singleton

package com.company.com;
import com.company.dao.UserDao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTest {
@Test
//测试scope属性
public void test1() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao1 = (UserDao) applicationContext.getBean("userDao");
UserDao userDao2 = (UserDao) applicationContext.getBean("userDao");
System.out.println(userDao1);
System.out.println(userDao2);
}
}
要看对象是否是同一个,只要看他们的地址就行了

当scope取值为singleton时:
Bean实例化个数:1个
Bean实例化时机:当Spring核心文件被加载时,实例化配置的Bean实例
Bean的生命周期:
- 对象创建:当应用加载,创建容器时,对象就被创建
- 对象运行:只要容器在,对象一直活着
- 对象销毁:当应用卸载,销毁容器时,对象就被销毁了

配置成prototype时


可以看到两个对象的地址不一样,说明不是同一个对象,每次都是new出来一个新的。容器中存在UserDaoImpl对象不止一个。
当scope取值为prototype时
Bean的实例化个数:多个
Bean的实例化时机:当调用getBean()方法时实例化Bean
Bean的生命周期:
- 对象创建:当使用对象时,创建新的对象实例
- 对象运行:只要对象在使用中,对象一直活着
- 对象销毁:当对象长时间不用时,就会被java垃圾回收器回收

package com.company.com;
import com.company.dao.UserDao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTest {
@Test
//测试scope属性
public void test1() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao1 = (UserDao) applicationContext.getBean("userDao");
System.out.println(userDao1);
}
}
3.Bean生命周期配置
init-method:指定类中的初始化方法名称
destroy-method:指定类中销毁方法名称
这个对象如果创建完毕,我想让它执行初始化的工作,我可以调用init方法;如果这个对象销毁之前,我想让它执行一些销毁的动作,我可以调用destroy
通过配置的方式,告诉Spring,我这个Bean有初始化方法,有销毁方法,一会儿要帮我执行下。
package com.company.dao.impl;
import com.company.dao.UserDao;
public class UserDaoImpl implements UserDao {
public UserDaoImpl() {
System.out.println("UserDaoImpl创建...");
}
public void init() {
System.out.println("初始化方法....");
}
public void destroy() {
System.out.println("销毁方法....");
}
public void save() {
System.out.println("save running...");
}
}


为什么没有打印销毁的那个方法呢?
因为还没有来得及打印,就销毁了。
下面我把容器手动关闭,手动关闭时,容器意识到自己要挂了,在挂之前,把内部的某些对象的销毁方法执行一下。
package com.company.com;
import com.company.dao.UserDao;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTest {
@Test
//测试scope属性
public void test1() {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao1 = (UserDao) applicationContext.getBean("userDao");
System.out.println(userDao1);
applicationContext.close();
}
}

4.Bean实例化的三种方式
都是在配置文件中修改,applicationContext.xml
(1)无参构造方法实例化

(2)工厂静态方法实例化

package com.company.factory;
import com.company.dao.UserDao;
import com.company.dao.impl.UserDaoImpl;
public class StaticFactory {
public static UserDao getUserDao() {
return new UserDaoImpl();
}
}

Spring在解析的时候,发现你这个applicationContext.xml中,有一个factory-method,就找这个全包名com.company.factory.StaticFactory对应的内部指定的方法去返回对应的对象。

因为是静态的,所以可以直接调用这个factory-method,即getUserDao
(3)工厂实例方法实例化
方法不是静态的了,因此必须先有工厂对象,再去调用方法getUserDao
所以,先把工厂对象让Spring产生(通过无参构造的方式),再去调用工厂的某个方法
