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产生(通过无参构造的方式),再去调用工厂的某个方法