之前说到关于读取.properties文件的方式来创建Bean,现在spring正式登场。
首先创建Bean文件(后缀为.xml格式),格式如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> </beans>
接着,读取.xml文件的方式如下,读取之前,首先要了解
ApplicationContext
接口,以及它有三个实现类:
ClassPathXmlApplicationContext
FileSystemXmlApplicationContext
AnnotationConfigApplicationContext
ClassPathXmlApplicationContext的操作流程如下:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
注意:这里读取的是resource根目录下的bean.xml文件,这样我们就加载了所有的Bean,那么具体用到哪个就取哪个就可以了
AccountService accountService = (AccountService) applicationContext.getBean("accountService");
此处注意要强转一下,因为applicationContext获取的都是Object对象。
FileSystemXmlApplicationContext的操作流程如下:
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("F:\\vertx\\springpractise\\src\\main\\resources\\bean.xml");
可以看到,这是根据绝对路径来读取文件的。
AnnotationConfigApplicationContext暂时未写明,后期会有。
那么话说回来,到底Bean文件该怎么写呢?
答案是:spring创建Bean有三种方式:
<!--第一种方式:使用默认构造函数创建 在spring的配置文件中使用bean标签,配以ID和class属性后,且没有其他属性和标签时。 采用的就是默认的默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建--> <bean id="accountService" class="com.springpractise.demo.service.AccountServiceImpl"></bean> <!--第二种方法,使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器)--> <bean id="instanceFactory" class="com.springpractise.demo.test.FactoryInstanceFactory"></bean> <bean id="accountService1" factory-bean="instanceFactory" factory-method="getAccountService"></bean> <!--第三种方式:使用工厂中的静态方法创建对象,使用某个类中的静态方法创建对象,并存入spring容器--> <bean id="accountService2" class="com.springpractise.demo.test.StaticFactory" factory-method="getAccountService"></bean>
其中,对应的com.springpractise.demo.test.FactoryInstanceFactory文件是:
package com.springpractise.demo.test; import com.springpractise.demo.service.AccountService; import com.springpractise.demo.service.AccountServiceImpl; public class FactoryInstanceFactory { public AccountService getAccountService(){ return new AccountServiceImpl(); } }
com.springpractise.demo.test.StaticFactory对应的文件是:
package com.springpractise.demo.test; import com.springpractise.demo.service.AccountService; import com.springpractise.demo.service.AccountServiceImpl; public class StaticFactory { public static AccountService getAccountService(){ return new AccountServiceImpl(); } }
此处有个疑惑点,第二种和第三种到底适用于什么场景?这边还在网上搜索答案。有结果了再补充。
接下来是所有的代码:
package com.springpractise.demo.client; import com.springpractise.demo.Dao.AccountDao; import com.springpractise.demo.service.AccountService; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; public class Clinet { /** * 获取spring的IOC核心容器,并根据ID获取对象 * * ApplicationContext的三个常用的实现类: * ClassPathXmlApplicationContext:它可以加载类路径下的配置文件,要求配置文件必须在类路径下。不在的话,加载不了(更常用) * FileSystemXmlApplicationContext:它可以加载磁盘任意路径下的配置文件(必须要有访问权限) * AnnotationConfigApplicationContext:用于读取注解创建的内容 * * 核心容器的两个接口引发的问题: * ApplicationContext: 单列对象适用 * 它在构建核心容器的时候,创建对象采取的策略是采用立即加载的方式。也就是说,只要一读取完配置文件马上就创建配置文件中的对象 * BeanFactory: 多列对象适用 * 它在构建核心容器的时,创建对象采取的策略是采用延迟加载的方式,也就是说什么时候根据ID获取对象了,什么时候才真正的创建 * @param args */ public static void main(String[] args) { //获取核心容器对象 //ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml"); ApplicationContext applicationContext = new FileSystemXmlApplicationContext("F:\\vertx\\springpractise\\src\\main\\resources\\bean.xml"); //根据ID获取Bean对象 AccountService accountService = (AccountService) applicationContext.getBean("accountService"); AccountDao accountDao = applicationContext.getBean("accountDao",AccountDao.class); System.out.println(accountService); System.out.println(accountDao); accountDao.saveAccount(); //------BeanFactory------- Resource resource = new ClassPathResource("bean.xml"); BeanFactory beanFactory = new XmlBeanFactory(resource); AccountDao accountService1 = (AccountDao) beanFactory.getBean("accountDao"); System.out.println(accountService1); AccountService accountService2 = (AccountService) applicationContext.getBean("accountService"); accountService2.saveAccount(); AccountService accountService3 = (AccountService) applicationContext.getBean("accountService2"); accountService3.saveAccount(); } }
Bean.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--把对象的创建交给spring管理--> <!--spring对bean的管理细节 1.创建Bean的三种方式 2.bean对象的作用范围 3.bean对象的生命周期 --> <!--创建Bean的三种方式--> <!--第一种方式:使用默认构造函数创建 在spring的配置文件中使用bean标签,配以ID和class属性后,且没有其他属性和标签时。 采用的就是默认的默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建--> <bean id="accountService" class="com.springpractise.demo.service.AccountServiceImpl"></bean> <!--第二种方法,使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器)--> <bean id="instanceFactory" class="com.springpractise.demo.test.FactoryInstanceFactory"></bean> <bean id="accountService1" factory-bean="instanceFactory" factory-method="getAccountService"></bean> <bean id="accountDao" class="com.springpractise.demo.Dao.AccountDaoImpl"></bean> <!--第三种方式:使用工厂中的静态方法创建对象,使用某个类中的静态方法创建对象,并存入spring容器--> <bean id="accountService2" class="com.springpractise.demo.test.StaticFactory" factory-method="getAccountService"></bean> </beans>