工厂模式
工厂模式概述:
工厂模式是一种常见的设计模式。是一种通过工厂方法,代替new操作,帮助我们创建对象的设计模式。
工厂模式解耦基础版本
编写工厂类四个基本步骤
-第一步:
声明一个私有的工厂类对象引用
-第二步:
把构造方法私有化
-第三步:
通过静态代码块初始化
-第四步:
提供一个公有的、静态的方法,获取工厂类对象引用
工厂模式解耦改良
改良思路:
1.通过配置文件,将要创建的目标对象的类型信息,进行配置
2.在工厂类中加载配置文件,通过反射技术实现运行时加载,并创建目标对象
工厂模式解耦理解
在实际项目开发中,我们可以通过配置文件把service、dao对象配置起来,当启动服务器加载应用的时候,读取配置文件,创建配置文件中的对象并且保存起来。在接下来实际使用的地方,直接拿过来使用即可。此时我们需要考虑两个问题:
问题一:将对象存放在什么地方?
由于在一个应用中,会需要大量的对象,首先考虑把对象存储到什么地方。在java中有对应的集合List和Map。选择什么好呢?考虑到我们有查找的需求,那么选择Map比较好。
。
问题二:什么是工厂呢?
工厂就是负责创建对象,并且把对象放到容器中。在实际使用的时候,帮助我们从容器获取指定的对象。此时我们获取对象的方式发生了改变。
tips:原来我们获取对象时,都是采用new的方式。是主动获取.
现在我们获取对象时,找工厂要,由工厂创建并且提供给我们。是被动接收
结论:
这种获取对象方式的转变(由原来主动获取,到现在被动接收),我们称它为控制反转。控制反转,即IOC(Inversion Of Control)。
IOC,其实它就是我们刚才的工厂模式解耦。
原来获取对象的方式:

现在获取对象的方式:

Spring
概述
spring框架是J2EE企业级应用的轻量级开源框架。它是以IOC(Inversion Of Control)控制反转、和AOP(Aspect Oriented Programming)面向切面编程为核心;提供了表现层springmvc和持久层spring JDBC,以及业务层的事务管理等企业级应用解决方案;还能实现将开源世界中众多优秀的第三方框架整合,成为越来越受欢迎的J2EE企业级应用框架。
spring框架发展历程
-
1997年IBM提出了EJB的思想
-
1998年,SUN制定开发标准规范EJB1.0
-
1999年,EJB1.1发布
-
2001年,EJB2.0发布
-
2003年,EJB2.1发布
-
2006年,EJB3.0发布
-
Rod Johnson(spring之父)
Expert One-to-One J2EE Design and Development(2002)
阐述了J2EE 使用EJB 开发设计的优点及解决方案
Expert One-to-One J2EE Development without EJB(2004)
阐述了J2EE 开发不使用EJB 的解决方式(Spring 雏形)
-
2017 年9 月份发布了spring 的最新版本spring 5.0 通用版(GA)
image.png
Spring框架优点
IOC解耦,简化开发
通过spring提供的IOC容器,可以将对象间的依赖关系交由spring管理,避免硬编码造成的程序间过渡耦合
AOP面向切面编程
通过spring的AOP功能,方便实现面向切面编程,很多使用传统OOP编程不容易实现的业务功能,可以通过AOP轻松实现。比如事务管理,日志功能。
声明式事务管理
通过声明式方式灵活实现事务管理,提高开发效率和质量,将我们(程序员)从单调烦闷的事务管理代码中解脱出来
整合第三方优秀框架
spring框架降低了第三方框架的集成使用难度,提供了对各种框架(quartz、mybatis、springmvc等)的直接支持
spring框架体系结构

spring 基于xml配置IOC
spring IOC介绍
IOC(Inversion Of Control)控制反转。指的是获取对象方式由原来主动获取,到被动接收的转变。在spring中,IOC就是工厂模式解耦,是spring框架用于创建对象和管理对象的容器。
官网
下载
http://repo.springsource.org/libs-release-local/org/springframework/spring/
搭建spring IOC环境
配置pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.heaven</groupId>
<artifactId>spring-day01-03helloworld</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<!--依赖版本-->
<properties>
<!-- spring版本 -->
<spring.version>5.0.2.RELEASE</spring.version>
</properties>
<!--依赖包-->
<dependencies>
<!--spring ioc依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</project>
编写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">
<!--配置service,说明:
标签:
bean:配置javaBean对象
属性:
id:bean的唯一标识名称
class:类的全路径信息
细节:
默认使用无参数构造方法,创建对象
-->
<bean id="customerService" class="com.itheima.service.impl.CustomerServiceImpl"></bean>
<!--配置dao-->
<bean id="customerDao" class="com.itheima.dao.impl.CustomerDaoImpl"></bean>
</beans>
spring 工厂类结构
spring 工厂类结构

spring bean标签
bean标签作用
bean标签作用:
配置javaBean对象。
spring框架遇到bean标签,默认调用无参数构造方法实例化对象。
bean标签属性

bean作用范围和生命周期

案例:
<!--配置dao,说明:
标签:
bean:配置javaBean对象
属性:
id:bean的唯一标识名称
class:类的全路径信息
scope:设置bean的作用范围
取值:
singleton:单例(默认)
prototype:多例
细节:
默认使用无参数构造方法,创建对象
-->
<bean id="customerDao" class="com.itheima.dao.impl.CustomerDaoImpl"></bean>

singleton
<!--配置dao,说明:
标签:
bean:配置javaBean对象
属性:
id:bean的唯一标识名称
class:类的全路径信息
scope:设置bean的作用范围
取值:
singleton:单例(默认)
prototype:多例
细节:
默认使用无参数构造方法,创建对象
-->
<bean id="customerDao" class="com.itheima.dao.impl.CustomerDaoImpl"
scope="singleton"
></bean>

prototype
<!--配置dao,说明:
标签:
bean:配置javaBean对象
属性:
id:bean的唯一标识名称
class:类的全路径信息
scope:设置bean的作用范围
取值:
singleton:单例(默认)
prototype:多例
细节:
默认使用无参数构造方法,创建对象
-->
<bean id="customerDao" class="com.itheima.dao.impl.CustomerDaoImpl"
scope="prototype"
></bean>

init-method与destroy-method
配置bean.xml
<!--配置dao,说明:
标签:
bean:配置javaBean对象
属性:
id:bean的唯一标识名称
class:类的全路径信息
scope:设置bean的作用范围
取值:
singleton:单例(默认)
prototype:多例
init-method:初始化操作,在调用构造方法执行后执行
destroy-method:销毁操作,在销毁spring IOC容器前执行
细节:
默认使用无参数构造方法,创建对象
-->
<bean id="customerDao" class="com.heaven.dao.impl.CustomerDaoImpl"
scope="singleton" init-method="init" destroy-method="destroy"
></bean>
spring 实例化bean三种方式
spring框架有三种创建对象的方式
无参数构造方法实例化(重点)
<!--配置dao,说明:
标签:
bean:配置javaBean对象
属性:
id:bean的唯一标识名称
class:类的全路径信息
scope:设置bean的作用范围
取值:
singleton:单例(默认)
prototype:多例
init-method:初始化操作,在调用构造方法执行后执行
destroy-method:销毁操作,在销毁spring IOC容器前执行
细节:
默认使用无参数构造方法,创建对象
-->
<bean id="customerDao" class="com.heaven.dao.impl.CustomerDaoImpl"
scope="singleton" init-method="init" destroy-method="destroy"
></bean>
静态工厂方法实例化
编写工厂类
import com.heaven.dao.CustomerDao;
import com.heaven.dao.impl.CustomerDaoImpl;
/**
* 学习静态工厂方法,实例化对象
*/
public class StaticFactoryBean {
/**
* 工厂方法,注意:static关键子。该方法是静态的
*/
public static CustomerDao createCustomerDao(){
// 返回结果
CustomerDao customerDao = null;
System.out.println("静态工厂方法实例化对象----------------------start");
customerDao = new CustomerDaoImpl();
System.out.println("静态工厂方法实例化对象----------------------end");
return customerDao;
}
}
配置bean.xml
<!--静态工厂方法实例化对象,说明:
属性:
id:唯一标识名称
class:类全路径
factory-method:指定工厂方法
-->
<bean id="staticDao" class="com.heaven.factory.StaticFactoryBean" factory-method="createCustomerDao"></bean>
实例工厂方法实例化
编写工厂类
import com.heaven.dao.CustomerDao;
import com.heaven.dao.impl.CustomerDaoImpl;
/**
* 学习实例工厂方法,实例化对象
*/
public class InstanceFactoryBean {
/**
* 工厂方法,注意:该方法是一个普通方法
*/
public CustomerDao createCustomerDao(){
// 返回结果
CustomerDao customerDao = null;
System.out.println("实例工厂方法实例化对象----------------------start");
customerDao = new CustomerDaoImpl();
System.out.println("实例工厂方法实例化对象----------------------end");
return customerDao;
}
}
配置bean.xml
<!--实例工厂方法实例化对象,说明:
第一步:配置静态工厂对象
第二步:
factory-bean:指定工厂对象
factory-method:指定工厂方法
-->
<bean id="instanceFactory" class="com.heaven.factory.InstanceFactoryBean"></bean>
<bean id="instanceDao" factory-bean="instanceFactory" factory-method="createCustomerDao"></bean>
spring依赖注入
依赖注入(Dependency Injection),它是spring框架核心IOC的具体实现。用于维护应用程序中,层与层之间、对象与对象之间的关系。
依赖注入就是给类的成员变量赋值。
两种类型(构造方法、set)
构造方法注入
通过构造方法,给类的成员变量赋值
编写构造方法注入
/**
* 学习构造方法注入数据
*/
public class ConstructorDaoImpl implements CustomerDao{
// 类的成员变量
private int id;
private String name;
private Integer age;
private Date birthday;
//====================================构造方法=============================
public ConstructorDaoImpl(int id, String name, Integer age, Date birthday) {
this.id = id;
this.name = name;
this.age = age;
this.birthday = birthday;
}
/**
* 保存客户操作
*/
public void saveCustomer() {
System.out.println("id="+id+",name="+name+",age="+age+",birthday="+birthday);
}
}
配置bean.xml
<!--构造方法注入数据,说明:
标签:
constructor-arg:指定通过构造方法给成员变量赋值
属性:
index:成员变量在构造方法参数列表中的索引
name:成员变量的名称(与index使用一个即可,实际项目中用的更多)
type:成员变量的类型(默认即可)
value:给java简单类型成员变量赋值(八种基本类型+字符串String)
ref:给其他bean类型成员变量赋值
-->
<bean id="constructDao" class="com.itheima.dao.impl.ConstructorDaoImpl">
<constructor-arg index="0" name="id" type="int" value="1" ></constructor-arg>
<constructor-arg name="name" value="小明"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>
<!--配置java.util.Date-->
<bean id="now" class="java.util.Date"></bean>
set方法注入
set方法注入,就是通过set方法,给类的成员变量赋值
编写set方法注入类
public class SetDaoImpl implements CustomerDao{
// 类的成员变量
private int id;
private String name;
private Integer age;
private Date birthday;
//====================================set方法=============================
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
/**
* 保存客户操作
*/
public void saveCustomer() {
System.out.println("id="+id+",name="+name+",age="+age+",birthday="+birthday);
}
}
配置bean.xml
<!--set方法注入数据,说明:
标签:
property:指定通过set方法,给类的成员变量赋值
属性:
name:指定成员变量名称
value:给java简单类型成员变量赋值(八种基本类型+字符串String)
ref:给其他bean类型成员变量赋值
-->
<bean id="setDao" class="com.heaven.dao.impl.SetDaoImpl">
<property name="id" value="2"></property>
<property name="name" value="小花"></property>
<property name="age" value="18"></property>
<property name="birthday" ref="now"></property>
</bean>
依赖注入简化配置方式
p名称空间注入和c名称空间注入
p:

c:
<!--c名称空间注入,说明:
第一步:导入c名称空间
xmlns:c="http://www.springframework.org/schema/c"
第二步:
c:属性名称 ==>给java简单类型成员变量赋值
c:属性名称-ref ==>给其他bean类型成员变量赋值
-->
<bean id="cDao" class="com.itheima.dao.impl.ConstructorDaoImpl"
c:id="4" c:name="小黄" c:age="18" c:birthday-ref="now"
></bean>
集合属性依赖注入
成员变量是集合(MapList
Set`Array)的赋值
编写集合类型成员变量类
public class CollectionDaoImpl implements CustomerDao {
// 集合类型成员变量
private String[] array;
private List<String> list;
private Set<String> set;
private Map<String,String> map;
private Properties prop;
//===========================================set方法
public void setArray(String[] array) {
this.array = array;
}
public void setList(List<String> list) {
this.list = list;
}
public void setSet(Set<String> set) {
this.set = set;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setProp(Properties prop) {
this.prop = prop;
}
/**
* 保存客户操作
*/
public void saveCustomer() {
System.out.println(array !=null? Arrays.asList(array):"");
System.out.println(list);
System.out.println(set);
System.out.println(map);
System.out.println(prop);
}
}
配置bean.xml
<!--讲解集合属性注入,说明:
1.List结构:
array/list/set
2.Map结构:
map/prop
3.数据结构一致,标签可以互换
-->
<bean id="collectionDao" class="com.heaven.dao.impl.CollectionDaoImpl">
<!--array-->
<property name="array">
<array>
<value>array1</value>
<value>array2</value>
</array>
</property>
<!--list-->
<property name="list">
<list>
<value>list1</value>
<value>list2</value>
</list>
</property>
<!--set-->
<property name="set">
<set>
<value>set1</value>
<value>set2</value>
</set>
</property>
<!--map-->
<property name="map">
<map>
<entry key="map-k1" value="map-v1"></entry>
<entry key="map-k2" value="map-v2"></entry>
</map>
</property>
<!--prop-->
<property name="prop">
<props>
<prop key="prop-k1">prop-v1</prop>
<prop key="prop-k2">prop-v2</prop>
</props>
</property>
</bean>
spring基于注解配置IOC
客户dao实现类
@Component("customerDao")
public class CustomerDaoImpl implements CustomerDao {
/**
* 保存客户操作
*/
public void saveCustomer() {
System.out.println("保存客户操作。");
}
}
改造service实现类
*/
@Component("customerService")
public class CustomerServiceImpl implements CustomerService {
// 定义客户dao
@Autowired
private CustomerDao customerDao;
/**
* 保存客户操作
*/
public void saveCustomer() {
customerDao.saveCustomer();
}
}
配置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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--配置包扫描注解配置dao/service,说明:
第一步:导入context名称空间和约束
第二步:
通过<context:component-scan>标签配置包扫描。spring框架在创建IOC容器的时候,
会扫描指定的包,和它的子包
-->
<context:component-scan base-package="com.heaven"></context:component-scan>
<!--配置service
<bean id="customerService" class="com.heaven.service.impl.CustomerServiceImpl">
<property name="customerDao" ref="customerDao"></property>
</bean>-->
<!--配置dao
<bean id="customerDao" class="com.heaven.dao.impl.CustomerDaoImpl"></bean>-->
</beans>
改造客户controller
/**
* 客户controller
*/
public class CustomerController {
public static void main(String[] args) {
/**
* 学习注解配置spring IOC:
* 细节:
* 1.在加载spring配置文件bean.xml,创建spring IOC容器的时候,需要加上(classpath:)
* 2.从功能实现上,可以加上,也可以不加。spring框架建议我们加上
*/
// 1.加载spring配置文件,创建spring ioc容器
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean.xml");
// 2.从容器中获取客户service对象
CustomerService customerService = (CustomerService)context.getBean("customerService");
// 保存客户
customerService.saveCustomer();
}
}
常用注解
创建对象相关的注解
@Component
作用:
配置javaBean对象。相当于xml配置方式中的bean标签
属性:
value:给bean一个唯一标识名称
细节:
1.value属性可以省略
2.默认使用类的名称首字母小写,作为bean的名称
@controller、@Service、@Repository
由@Component演化的三个注解:
@Controller:一般用于表现层
@Service:一般用于业务层
@Repository:一般用于持久层
scope
作用:
设置bean的作用范围,相当于xml配置方式中bean标签的scope属性。
属性:
value:指定作用范围取值
属性取值:
singleton:单例。默认值
prototype:多例。
request:web项目中,把bean对象存入request域中
session:web项目中,把bean对象存入全局session域中
注入数据相关的注解
@Autowired
作用:
默认按照bean的类型注入数据
属性:
required:指定目标bean是否必须存在于spring的IOC容器(true必须存在;false:可以不存在;默认true)
细节:
1.在spring容器中,如果同一个类型存在多个bean实例对象
2.则先按照bean的类型进行注入,再按照bean的名称进行匹配
3.匹配上注入成功;匹配不上注入失败
@Qualifier
作用:
:
与@Autowired注解一起使用,指定在按照bean类型注入的基础上,再按照bean的名称注入。
属性:
value,指定bean的名称。
细节:
1.在类的成员变量上,不能单独使用。需要与@Autowired注解一起使用。
2.在方法的成员变量上,可以单独使用。
@Resource
作用:
默认按照bean的名称注入数据。
属性:
name:指定bean的名称注入数据
type:指定bean的类型注入数据
细节:
默认按照bean的名称匹配注入数据。如果注入失败,再按照bean的类型注入
Value
给java简单数据类型注入数据。
与bean生命周期相关的注解
@PostConstruct
初始化操作,相当于xml配置方式中bean 标签的init-method属性
@PreDestroy
销毁操作,相当于xml配置方式中bean 标签的destroy-method属性
注解完整案例代码参考——
CustomerServiceImpl
/**
* 客户service实现类,学习常用注解:
* 1.创建对象相关的注解:
* @Component:
* 作用:配置javaBean对象。相当于xml配置方式中的bean标签
* 属性:
* value:给bean一个唯一标识名称
* 细节:
* 1.value属性可以省略
* 2.默认使用类的名称首字母小写,作为bean的名称
*
* @Controller、@Service、@Repository:由@Component衍生的三个注解,衍生的目的是语义更加明确
* @Controller:一般用于表现层
* @Service:一般用于业务层
* @Repository:一般用于持久层
*
* 2.设置bean作用范围相关的注解:
* @Scope:
* 作用:设置bean的作用范围。相当于xml配置方式中bean标签的scope属性
* 属性:
* value:指定作用范围取值
* 属性取值:
* singleton:单例。默认值
* prototype:多例
* request:web项目中,把bean对象存入request域中【了解】
* session:web项目中,把bean对象存入session域中【了解】
* globalsession:web项目中,把bean对象存入全局session域中【了解】
*
* 3.注入数据相关的注解:
* @Autowired:
* 作用:默认按照bean的类型注入数据
* 属性:
* required:指定目标bean是否必须存在于spring的IOC容器(true必须存在;false:可以不存在;默认true)
* 细节:
* 1.在spring容器中,如果同一个类型存在多个bean实例对象
* 2.则先按照bean的类型进行注入,再按照bean的名称进行匹配
* 3.匹配上注入成功;匹配不上注入失败
*
* @Qualifier:
* 作用:与@Autowired注解一起使用,指定在按照bean类型注入的基础上,再按照bean的名称注入
* 属性:
* value:指定bean的名称
* 细节:
* 1.在类的成员变量上,不能单独使用。需要与@Autowired注解一起使用
* 2.在方法的成员变量上,可以单独使用
*
* @Resource:
* 作用:默认按照bean的名称注入数据
* 属性:
* name:指定bean的名称注入数据
* type:指定bean的类型注入数据
* 细节:
* 默认按照bean的名称匹配注入数据。如果注入失败,再按照bean的类型注入
*
* @Value:
* 作用:给java简单类型成员变量注入数据
*
* 4.与bean的生命周期相关的注解:
* @PostConstruct:
* 初始化操作,相当于xml配置方式中bean标签的init-method属性
* @PreDestroy:
* 销毁操作,相当于xml配置方式中bean标签的destroy-method属性
*
*/
@Service("customerService")
@Scope(value = "singleton")
public class CustomerServiceImpl implements CustomerService {
// 定义客户dao
/*@Autowired
@Qualifier(value = "customerDao1")*/
//@Resource(name = "customerDao1")
@Resource(type = CustomerDaoImpl.class)
private CustomerDao customerDao;
// java简单类型成员变量
@Value("1")
private int id;
@Value("小明")
private String name;
/**
* 初始化操作
*/
@PostConstruct
public void init(){
System.out.println("正在执行初始化操作......");
}
/**
* 销毁操作
*/
@PreDestroy
public void destroy(){
System.out.println("正在执行销毁操作......");
}
/**
* 保存客户操作
*/
public void saveCustomer() {
System.out.println("id="+id+",name="+name);
customerDao.saveCustomer();
}
}
CustomerController
/**
* 客户controller
*/
public class CustomerController {
public static void main(String[] args) {
/**
* 学习常用注解
*/
// 1.加载spring配置文件,创建spring ioc容器
//ApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean.xml");
// 2.从容器中获取客户service对象
/**
* 创建对象相关的注解:@Component、@Controller、@Service、@Repository
*/
/*CustomerService customerService = (CustomerService)context.getBean("customerService");*/
/**
* 设置bean的作用范围相关的注解:@Scope
*/
/* CustomerService customerService = (CustomerService)context.getBean("customerService");
CustomerService customerService1 = (CustomerService)context.getBean("customerService");
System.out.println(customerService==customerService1);
System.out.println(customerService.hashCode());
System.out.println(customerService1.hashCode());*/
/**
* 注入数据相关的注解:@Autowired、@Qualifier、@Resource、@Value
*/
/* CustomerService customerService = (CustomerService)context.getBean("customerService");*/
/**
* 与bean生命周期相关的注解:@PostConstruct、@PreDestroy
*/
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean.xml");
CustomerService customerService = (CustomerService)context.getBean("customerService");
// 保存客户
customerService.saveCustomer();
// 销毁容器
context.close();
}
}
网友评论