4、创建第一个SpringDemo
4.1搭建框架
4.2 具体代码
4.2.1 dao
package com.zhc1024.dao;
public interface CustomerDao {
/**
* 保存操作
*/
void save();
}
4.2.2 dao.impl
package com.zhc1024.dao.impl;
import com.zhc1024.dao.CustomerDao;
public class CustomerDaoImpl implements CustomerDao {
public void save() {
System.out.println("保存成功!");
}
}
4.2.3 service
package com.zhc1024.service;
public interface CustomerService {
/**
* 保存操作
*/
void save();
}
4.2.4 service.impl
package com.zhc1024.service.impl;
import com.zhc1024.dao.impl.CustomerDaoImpl;
import com.zhc1024.service.CustomerService;
public class CustomerServiceImpl implements CustomerService {
private CustomerDaoImpl customerDao = new CustomerDaoImpl();
public void save() {
customerDao.save();
}
}
4.2.5 编写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">
<!--
说明:
bean:IOC容器管理单位
id:唯一标识
class:路径信息
-->
<!--配置service-->
<bean id="customerService" class="com.zhc1024.service.impl.CustomerServiceImpl"></bean>
<!--配置dao-->
<bean id="customerDao" class="com.zhc1024.dao.impl.CustomerDaoImpl"></bean>
</beans>
4.2.6 controller
package com.zhc1024.controller;
import com.zhc1024.service.CustomerService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CustomerController {
public static void main(String[] args) {
/*
* 使用ApplicationContext获取对象
* 1.接口名称:ApplicationContext,上下文对象,负责创建管理bean,
* 2.实现类:ClassPathXmlApplicationContext 从项目中加载配置文件
*
* */
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
CustomerService customerService = (CustomerService) ac.getBean("customerService");
customerService.save();
}
}
4.2.7 运行结果
4.3 ApplicationContext和BeanFactory的区别
主要是创建对象的时间差别,BeanFactory是用到的时候才创建对象,ApplicationContext是加载配置文件就创建。一般使用ApplicationContext,因为BeanFactory有的属性方法,ApplicationContext都有,所有的Bean在启动的时候都加载,系统运行的速度快; 在启动的时候所有的Bean都加载了,我们就能在系统启动的时候,尽早的发现系统中的配置问题;
4.3.1 使用ApplicationContext加载文件
改造dao实现类
package com.zhc1024.dao.impl;
import com.zhc1024.dao.CustomerDao;
public class CustomerDaoImpl implements CustomerDao {
//添加无参构造方法,因为是无参注入
public CustomerDaoImpl(){
System.out.println("我是无参构造方法");
}
public void save() {
System.out.println("保存成功!");
}
}
改造controller
package com.zhc1024.controller;
import com.zhc1024.service.CustomerService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CustomerController {
public static void main(String[] args) {
/*
* 使用ApplicationContext获取对象
* 1.接口名称:ApplicationContext,上下文对象,负责创建管理bean,
* 2.实现类:ClassPathXmlApplicationContext 从项目中加载配置文件
*
* */
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
System.out.println("配置加载完了");
CustomerService customerService = (CustomerService) ac.getBean("customerService");
customerService.save();
}
}
运行结果
我们可以看到是读取配置文件的时候就已经创建完成对象了,打印两次的的原因:spring容器调用一次,我们自己在service那里又调用一次。
4.3.2 使用BeanFactory加载文件
改造controller
package com.zhc1024.controller;
import com.zhc1024.service.CustomerService;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class CustomerController {
public static void main(String[] args) {
/*
* 使用ApplicationContext获取对象
* 1.接口名称:ApplicationContext,上下文对象,负责创建管理bean,
* 2.实现类:ClassPathXmlApplicationContext 从项目中加载配置文件
*
* */
Resource resource = new ClassPathResource("bean.xml");
BeanFactory ac = new XmlBeanFactory(resource);
System.out.println("配置加载完了");
CustomerService customerService = (CustomerService) ac.getBean("customerService");
customerService.save();
}
}
运行结果
我们可以看到是读取了配置文件之后还没有创建对象,等到需要的时候才创建
5、Bean标签
Bean是Spring中最小的基本单位,任何事物都可以看做一个Bean,Bean标签属性如下:
5.1 Bean属性
id:唯一标识
class:类全名
scope:设置Bean的取值范围
singleton:单例。默认值
prototype:多例
request:web项目中,将对象存入request域中
session:web项目中,将对象存入session域中
globalsession:web项目中,应用在集群环境,如果没有集群环境,相当于session
init-method:指定类中初始化方法的名称,在构造方法执行完毕后立即执行
destroy-method:指定勒种销毁方法的名称,在销毁spring容器前执行
5.2 生命周期
5.3 演示单例
5.3.1 改造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">
<!--演示单例,默认就是-->
<bean id="CustomerService" scope="singleton" class="com.zhc1024.service.impl.CustomerServiceImpl"/>
<bean id="CustomerDao" class="com.zhc1024.dao.impl.CustomerDaoImpl"/>
</beans>
5.3.2 改造controller
package com.zhc1024.controller;
import com.zhc1024.service.CustomerService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CustomerController {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
CustomerService customerService1 = (CustomerService) ac.getBean("CustomerService");
CustomerService customerService2 = (CustomerService) ac.getBean("CustomerService");
System.out.println("customerService1 = " + customerService1);
System.out.println("customerService2 = " + customerService2);
System.out.println(customerService1 == customerService2);
}
}
5.3.3 运行结果
5.4 演示多例
5.4.1 改造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">
<!--演示单例,默认就是-->
<bean id="CustomerService" scope="prototype" class="com.zhc1024.service.impl.CustomerServiceImpl"/>
<bean id="CustomerDao" class="com.zhc1024.dao.impl.CustomerDaoImpl"/>
</beans>
5.4.2 运行结果
5.3 演示初始化和销毁方法
5.3.1 改造dao实现类
package com.zhc1024.dao.impl;
import com.zhc1024.dao.CustomerDao;
public class CustomerDaoImpl implements CustomerDao {
public CustomerDaoImpl (){
System.out.println("我是构造方法");
}
public void init(){
System.out.println("正在初始化");
}
public void destroy(){
System.out.println("正在销毁");
}
public void save() {
System.out.println("保存成功!");
}
}
5.3.2 改造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">
<!--演示单例,默认就是-->
<bean id="CustomerService" scope="prototype" class="com.zhc1024.service.impl.CustomerServiceImpl"/>
<bean id="CustomerDao" init-method="init" destroy-method="destroy" class="com.zhc1024.dao.impl.CustomerDaoImpl"/>
</beans>
5.3.3 改造controller
package com.zhc1024.controller;
import com.zhc1024.service.CustomerService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CustomerController {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
CustomerService customerService = (CustomerService) ac.getBean("CustomerService");
customerService.save();
((ClassPathXmlApplicationContext) ac).close();
}
}
5.3.4 运行结果
5.3.5 Bean是如何被Spring管理的呢
Spring容器在初始化的时候将配置文件中bean以及相对应关系的配置都加入到ApplicationContext,通过循环反射将这些bean实例化,bean被它进行了管理
循环反射:将List中的bean加入到Map<String,Object>中,这里用反射将bean中的className属性转换为一个实例化的bean对象加入到了Map中
6、Spring实例化Bean的三种方式
6.1 无参构造方法
上面例子即为无参构造方法的创建方式
6.2 静态化工厂创建方式
6.2.3 创建一个工厂类
package com.zhc1024.factory;
import com.zhc1024.dao.CustomerDao;
import com.zhc1024.dao.impl.CustomerDaoImpl;
import com.zhc1024.service.CustomerService;
import com.zhc1024.service.impl.CustomerServiceImpl;
/**
* 静态工厂实例化bean
*/
public class StaticFactoryBean {
public static CustomerDao createCustomer(){
CustomerDao customerDao = null;
System.out.println("调用静态化工厂--开始");
customerDao = new CustomerDaoImpl();
System.out.println("调用静态化工厂--结束");
return customerDao;
}
}
6.2.3 改造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">
<bean id="customerDao" class="com.zhc1024.factory.StaticFactoryBean" factory-method="createCustomer"/>
</beans>
6.2.4 controller
package com.zhc1024.controller;
import com.zhc1024.dao.CustomerDao;
import com.zhc1024.service.CustomerService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CustomerController {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
CustomerDao customerDao = (CustomerDao) ac.getBean("customerDao");
customerDao.save();
((ClassPathXmlApplicationContext) ac).close();
}
}
6.2.5 运行结果
6.3 实例工厂创建方式
6.3.2 创建实例工厂
package com.zhc1024.factory;
import com.zhc1024.dao.CustomerDao;
import com.zhc1024.dao.impl.CustomerDaoImpl;
/**
* 实例化工厂
*/
public class InstanceFactory {
public CustomerDao instanceFactory(){
CustomerDao customerDao = null;
System.out.println("实例工厂创建开始");
customerDao = new CustomerDaoImpl();
System.out.println("实例工厂结束");
return customerDao;
}
}
6.3.3 修改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">
<!--<bean id="customerDao" class="com.zhc1024.factory.StaticFactoryBean" factory-method="createCustomer"/>-->
<bean id="customerDao" class="com.zhc1024.factory.InstanceFactory"></bean>
<bean id="customerDao2" factory-bean="customerDao" factory-method="instanceFactory"></bean>
</beans>
6.3.4 修改controller和运行结果
7、三种创建方式共同点和区别
7.1 相同点
都是加载配置文件的时候创建的,创建的时机一样
7.2 不同点
7.2.1 无参构造方式创建
其本质就是把类交给Spring自带的 工厂(BeanFactory)管理、由Spring自带的工厂模式帮我们维护和创建这个类。如果是有参构造方法,也可通过配置文件传入相应从初始化参数
7.2.2 静态工厂创建
其本质就是把类交给我们自己的静态工厂管理,Spring只是帮我们调用了静态工厂创建实例的方法,而创建实例的这个过程由我们自己的静态工厂实现的,在时机开发过程中,很多时候我们需要使用到第三方分jar包提供给我们的类,这个类没有构造方法,而是通过第三方提供的静态工厂创建,这时候我们想把第三方的jar里面的这个类交由Spring来管理的话,就可以使用Spring提供方的静态工厂创建实例的配置。
7.2.3 实例工厂创建
其本质就是把创建实例的工厂类交由Spring管理,同时把调用工厂类的方法创建实例的这个过程也交由Spring管理,创建实例的这个过程也是由我们自己配置的实例工厂内部实现的。在实际开发过程中,如Spring整合Hibernate就是通过这种方式实现的。但对于没有与Spring整合过的工厂类,我们一般就是自己用代码来管理。