1.BeanFactory的类间关系
SpringIOC容器类的结构最底层的接口 BeanFactory子接口: ApplicationContext
ClassPathXmlApplicationContext 针对类路径下的 xml 文件配置的方式AnnotationConfigApplicationContext 针对纯注解式开发配置的方式FileSystemXmlApplicationContext 针对系统路径下的xml文件配置的方式BeanFactory 和 ApplicationContext 区别BeanFactory 使用的懒加载的形式,对象在使用的时候才会创建ApplicationContext, 当程序启动的时候会直接加载配置文件创建对象 (web 推荐使用 )BeanFactory和ApplicationContext都是Spring框架中的核心接口,它们都可以作为Spring的容器来创建和管理bean。然而,它们在功能和使用上存在一些主要的区别。
接口层次:BeanFactory是Spring中最底层的接口,它定义了容器的基本功能,如实例化对象和管理bean的生命周期等。而ApplicationContext则是BeanFactory的子接口,同时也是更高级的容器,提供了更多的功能。
使用场景:BeanFactory面向Spring框架本身,其使用范围较为狭窄;而ApplicationContext则面向使用Spring框架的开发者,因此在实际开发中使用更为广泛。
功能丰富度:相较于BeanFactory,ApplicationContext提供了更多的功能,包括支持国际化、事件传播等。这使得ApplicationContext可以更好地满足复杂的应用需求。
@Test
public void test01(){
//创建Spring容器对象ApplicationContext
ApplicationContextac=
new ClassPathXmlApplicationContext("applicationContext.xml");
Object userDao=ac.getBean("userDao1");
System.out.println(userDao);
}
@Test
public void test02(){
//创建Spring容器对象BeanFactory
Resource resource=new ClassPathResource("applicationContext.xml");
BeanFactory beanFactory=new XmlBeanFactory(resource);
Object userDao1=beanFactory.getBean("userDao1");
System.out.println(userDao1);
}
2.getBean方法
getBean(" 对象 id 标识 ");getBean( 类对象 );getBean("对象id标识",类对象);
@Test public void test03(){ //创建Spring容器对象ApplicationContext ApplicationContextac= new ClassPathXmlApplicationContext("applicationContext.xml"); //缺点:获取对象的时候需要强制转换 //UserDao userDao=(UserDao)ac.getBean("userDao1"); //userDao.addUser(); //缺点:如果一个类有多个对象,则报错 //UserDao userDao=ac.getBean(UserDaoImpl.class); //userDao.addUser(); UserDaoImpl userDao1=ac.getBean("userDao1",UserDaoImpl.class); UserDaoImpl userDao2=ac.getBean("userDao2",UserDaoImpl.class); userDao1.addUser(); userDao2.addUser(); }
3.bean标签中的scope属性
scope属性的取值
singleton :表示创建的对象是单例的 ( 默认取值 )prototype :表示创建的对象是原型模型基于webrequest :表示创建的对象在 request 范围内session :表示创建的对象在 session 范围内globalSession : Spring5.X弃用
在Spring框架中,bean标签的scope属性决定了bean的实例化方式。具体来说,singleton和prototype是两种常见的作用域:
Singleton(单例模式):这是默认的作用域。当一个bean的作用域设置为singleton时,Spring IoC容器仅会创建这一个bean的一个实例。这个bean的实例会被缓存在容器中,之后如果其他地方需要使用到这个bean,Spring会直接从缓存中取出这个bean的实例,而不是重新创建一个新的实例。这意味着在整个应用程序的生命周期中,singleton作用域的bean只有一个实例。在某些情况下,这可以节省资源并确保数据的一致性。
Prototype(原型模式):与singleton不同,prototype作用域的bean会在每次请求时都被创建一个新的实例。这意味着每个bean都有自己的实例,并且它们之间不会相互影响。这种作用域适用于那些需要在不同请求中使用不同状态的bean。
实际上,除了上述两种作用域,Spring还支持其他几种作用域,如session、request和global但在实际开发中,singleton和prototype是最常用和最常见的两种作用域。为了更好地理解这两种作用域的差异,可以考虑以下例子:如果一个bean被设置为singleton作用域,那么无论在哪里注入或获取这个bean,得到的都是同一个实例。相反,如果一个bean被设置为prototype作用域,每次注入或获取这个bean时,都会得到一个新的实例。
4.创建的对象三种方式
a 、直接配置 bean 标签 id 对象的唯一标识 class 对象的全限定名b 、通过静态工厂来创建对象 ( 了解 )c 、通过非静态工厂来创建对象 ( 了解 )
无参数的构造器创建对象<beanid="userDao" class="com.qf.dao.UserDao"></bean>
有参数的构造器创建对象<!-- 2.有参的构造函数创建对象 --> <bean id="userDao" class="com.qf.dao.UserDao"> <constructor-arg index="0" type="int" value="18"></constructor-arg> <constructor-arg index="1" type="java.lang.String" value="张三"></constructor-arg> </bean>
静态工厂<!--方式二:静态工厂 class:工厂类 factory-method:静态工厂方法--> <bean id="userDao5" class="com.qf.factory.UserDaoFactory" factory-method="getUserDao1"/>
非静态工厂<!--方式三:非静态工厂 factory-bean:工厂类的对象 factory-method:工厂非静态方法--> <!--先创建工厂类的对象 --> <bean id="factory" class="com.qf.factory.UserDaoFactory"></bean> <bean id="userDao6" factory-bean="factory" factory-method="getUserDao2"></bean>
@Test public void test05(){ //创建Spring容器对象ApplicationContext ApplicationContextac= new ClassPathXmlApplicationContext("applicationContext.xml"); UserDaoImpl userDao4=ac.getBean("userDao4",UserDaoImpl.class); System.out.println(userDao4); UserDaoImpl userDao5=ac.getBean("userDao5",UserDaoImpl.class); System.out.println(userDao5); UserDaoImpl userDao6=ac.getBean("userDao6",UserDaoImpl.class); System.out.println(userDao6); }
5.创建对象的生命周期
SpringIOC 容器创建 Bean 的生命周期当创建的实例是单例模式:当Spring 容器创建的时候,对象就会被创建Spring容器关闭,就会销毁类的对象当创建的实例是原型模式:Spring容器创建,并不会初始化,而是什么时候使用,什么时候初始化
Spring容器关闭,不会销毁类的对象。而是交给 Java 内存回收机制
属性配置
<bean id="userDao7"class="com.qf.dao.impl.UserDaoImpl" scope="prototype" init-method="init" destroy-method="destroy"> </bean>
UserDaoImplpublic class UserDaoImpl implements UserDao{ @Override public int addUser(){ System.out.println("UserDaoImpl添加。。"); return0; } public void init(){ System.out.println("UserDaoImpl对象初始化"); } public void destroy(){ System.out.println("UserDaoImpl对象销毁"); } }
测试
/** * Spring容器创建对象的生命周期 * 使用ApplicationContext作为Spring容器, * 当创建的实例是单例模式: * 当Spring容器创建的时候,对象就会被创建Spring容器关闭, * 就会销毁类的对象 * 当创建的实例是原型模式: * Spring容器创建,并不会初始化,而是什么时候使用,什么时候初始化 * Spring容器创建,不会销毁类的对象。而是交给Java内存回收机制 */ @Test public void test06(){ //创建Spring容器对象ApplicationContext ClassPathXmlApplicationContextac= new ClassPathXmlApplicationContext("applicationContext.xml"); UserDaoImpl userDao7=ac.getBean("userDao7",UserDaoImpl.class); System.out.println(userDao7); //Spring容器关闭 ac.close(); }