【JavaEE学习笔记】Spring_01_工厂模式,Spring小程序,IoC控制反转

Spring_01

A.工厂模式

1.概述

是由专家总结出来的,在某种情况下解决某类问题的最佳解决方案

设计模式六大原则

单一职责原则

里氏替换原则

依赖倒置原则

接口隔离原则

迪米特法则

开闭原则

2.框架

是用于处理某种问题的半成品软件,共开发人员通过制定进行高效的开发

3.JavaSE的设计模式

什么是GOF(四人帮,全拼 Gang of Four)

在1994年由四人合著出版了一本名为

Design Patterns - Elements of Reusable Object-Oriented Software

(设计模式 - 可复用的面向对象软件元素)的书

该书首次提到了软件开发中设计模式的概念

GOF总结了JavaSE开发中常见的23种设计模式,可以分为3大类:

创建型模式、结构型模式、行为型模式

4.JavaEE模式

JavaEE设计模式特别关注表示层,如MVC模式(MVC Pattern)

数据访问对象模式DAO(Data Access Object Pattern) 

前端控制器模式(Front Controller Pattern)

5.Spring应用总体概述


6.Spring的核心思想(就是工厂模式)

不重复发明轮子理论

锤子理论

7.OOP

核心是面向抽象编程,面向抽象编程的核心是面向接口

a.IUSerDao接口

public interface IUserDao {
	void save(UserMBean user);
}

b.UserDaoImpl实现类

public class UserDaoImpl implements IUserDao {

	@Override
	public void save(UserMBean user) {
		
	}

}

接口的实现可能有多个,如何实现在多个接口具体实现之间进行切换

工厂模式

c.DaoFactory工厂

这是一种因为只有一种具体实现的退化写法

不是真正GOF提出的工厂设计模式

静态工厂方法[不是GOF的工厂模式]

public class DaoFactory {

	public static IUserDao getUserDao(String type) {
		if ("oracle".equals(type)) {
			return new OracleUserDaoImpl();
		}
		if ("mysql".equals(type)) {
			return new MysqlUserDaoImpl();
		}

		return new UserDaoImpl();
	}

}

8.工厂模式

设计模式属于创建型模式,它提供了一种创建对象的最佳方式

主要解决:主要解决接口实现的选择问题

优点:

一个调用者想创建一个对象,只要知道其名称就可以了

扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以

屏蔽产品的具体实现,调用者只关心产品的接口

缺点:

每次增加一个产品时,都需要增加一个具体类和对象实现工厂

使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度

同时也增加了系统具体类的依赖,这并不是什么好事


9.抽象工厂模式

是围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂

这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式

主要解决:提供一个创建一系列相关或相互依赖对象的接口,解决接口实现选择的问题

优点:

当一个产品族中的多个对象被设计成一起工作时

它能保证客户端始终只使用同一个产品族中的对象

缺点:

产品族扩展非常困难,要增加一个系列的某一产品

既要在抽象的 Creator 里加代码,又要在具体的里面加代码


10.Spring底层实现

引入资源文件,使用反射创建字串所指代的对象

Spring框架最重要是提供了以类似下面xml+BeanFactory的方式

管理配置在xml文件中的受管Bean

抽象产品接口IShape

package org.wpf.fac;

// 抽象产品接口
public interface IShape {
	void draw();
}
具体产品1 Circle

package org.wpf.fac;

public class Circle implements IShape {

	@Override
	public void draw() {
		System.out.println("画一个圆形");
	}

}

扩展颜色 IColor

package org.wpf.fac;

public interface IColor {
	void fill();
}

颜色实现 Red

package org.wpf.fac;

public class Red implements IColor {

	@Override
	public void fill() {
		System.out.println("红色代表热情");
	}

}

具体产品2 Sequare

package org.wpf.fac;

public class Sequare implements IShape {

	@Override
	public void draw() {
		System.out.println("绘制矩形");
	}

}

工厂 BeanFactory

package org.wpf.fac;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.naming.factory.BeanFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class BeanFactory {
	// 需求,当加载BeanFactory类时,则自动解析xml文件,并构建class所指定的类对象,以id值为key存放在一个集合中,
	// 每次获取产品实现时,只需要在集合中进行查找即可
	private static Map<String, Object> map = new HashMap<>();

	static {
		init();
	}

	private BeanFactory() {
	}

	public static Object getBean(String id) {
		if (map.containsKey(id)) {
			return map.get(id);
		}
		return null;
	}

	// 使用JAXP
	private static void init() {
		try {
			InputStream is = BeanFactory.class.getResourceAsStream("beans.xml");
			SAXParserFactory fac = SAXParserFactory.newInstance();
			// 获取当前系统默认使用的xml文件解析器
			SAXParser parser = fac.newSAXParser();
			parser.parse(is, new DefaultHandler() {
				@Override
				public void startElement(String uri, String localName, String qName, Attributes attributes)
						throws SAXException {
					// 参数uri是名空间,localName是xml标签的本地名,qName是xml标签的全局名称,attributes是标签的所有属性,存放方式类似于Map
					if ("bean".equals(qName)) {
						String id = attributes.getValue("id");// 获取<bean>标签中的id属性值
						String className = attributes.getValue("class");
						try {
							Object obj = Class.forName(className).newInstance();
							map.put(id, obj);
						} catch (Exception e) {
							throw new SAXException(e);
						}
					}
				}
			});
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

配置文件beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- 避免properties文件的缺点,xml配置文件可以通过dtd或者xsd的方式定义其中的语法规则 -->
<beans>
	<!-- bean配置,id表示不允许重复,这是名称,class是具体实现类的全名 -->
	<bean id="color" class="org.wpf.fac.Red"/>
	<bean id="shape" class="org.wpf.fac.Sequare"/>
</beans>

测试类

package org.wpf.fac;

public class Test {
	public static void main(String[] args) {
		IColor c = (IColor) BeanFactory.getBean("color");
		c.fill();
		
		IShape s = (IShape) BeanFactory.getBean("shape");
		s.draw();
	}
}

B.Spring初识

1.jar包

Spring最新为5.0.0 RC4,目前常用的是4.3.12 (2017年9月),目前支持JDK8/7/6等

beans、core、context、context-support和expression

[提供了一种表达式语言SpEL以简化配置文件]

实际上压缩文件中只包含Spring的jar包,

包含需要依赖的包  commons-logging


2.定义核心配置

src/applicationContext.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">

	<!-- id:受管理bean的名称,不重复 class:全类名 -->
	<bean id="color" class="org.wpf.spr.Red" />
</beans>

3.编码调用

package org.wpf.spr;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

@SuppressWarnings("deprecation")
public class Test {
	public static void main(String[] args) {
		// 读取配置文件
		Resource r = new ClassPathResource("applicationContext.xml");
		
		// 获取工厂
		BeanFactory fac = new XmlBeanFactory(r);
		
		IColor c = (IColor) fac.getBean("color");
		c.fill();
	}
}

4.Spring的IoC容器将面向接口的编程代价降到了最低

C.IoC控制反转

1.Spring概述

Spring是一个轻量级的控制反转IoC/DI依赖注入和面向切面AOP的开源容器框架

是一个开源的Java/Java EE全功能栈full-stack的应用程序框架

以Apache许可证形式发布,它由Rod Johnson创建

它是为了解决企业应用开发的复杂性而创建的

2002年Rod Johnson在他的Expert One-On-One Java EE Design and Development

一书中首次发布了这个框架,并奠定了作者的大师地位

该框架也可以移植到.NET的环境下

Spring框架本身并没有强制实行任何特别的编程模式

在Java社区里,Spring作为EJB模型之外的另外一个选择甚至是替代品而广为流行

从设计上看,Spring给予了Java程序员许多的自由度

但同时对业界常见的问题也提供了良好的文档和易于使用的方法

Spring框架的核心功能在任何Java应用中都是适用的

在基于Java企业平台上的web应用中,大量的拓展和改进得以形成

为此,Spring获得了广泛的欢迎,并被许多公司认可为具有战略意义的重要框架

Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情

[声明式事务管理  SessionBean会话bean用于封装业务处理逻辑 

EntityBean实体bean用于封装数据访问逻辑{BMP是bean管理的持久化

CMP容器管理的持久化} MessageDrivenBean消息驱动bean

用于实现异步的逻辑处理]

然而,Spring的用途不仅限于服务器端的开发

从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益

简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式解决方案)

轻量级开源框架

2.发展历程

2000年Spring框架最开始的部分是由Rod Johnson于2000年

为伦敦的金融界提供独立咨询业务时写出来的

在2002年编著的《Expert one on one J2EE design and development》一书中

对Java EE 系统框架臃肿、低效、脱离现实的种种现状提出了质疑

并积极寻求探索革新之道,发布了自己的代码(interface21)

以阐述“如何让应用程序能以超出当时大众所惯于接受的易用性

和稳定性与J2EE平台上的不同组件合作”的观点

2003年2月,一批自愿拓展Spring框架的程序开发人员组成了团队

在Sourceforge上构建了一个项目

2003年6月,Spring的框架首次在Apache 2.0的使用许可中发布

2004年3月在Spring框架上工作了一年之后,这个团队发布了第一个版本(1.0)

2005年,Spring框架的开发人员成立了自己的公司

来提供对Spring的商业支持,其中最显著的就是与BEA的合作

2009年VMware以4.2亿美元收购SpringSource,Spring开始向云计算方向发展

通过与VMware的合作计划为数据中心、私有云及公共云创建一个独立、集成

同时又融合了构建、运行及管理于一身的解决方案

Springboot  springdata springcloud

3.Maven进行Spring基础编程

建立Web工程,配置pom.xml文件

<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/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>org.wpf</groupId>
	<artifactId>spr</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>spr Maven Webapp</name>
	<url>http://maven.apache.org</url>
	<!-- 编码 -->
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
	</properties>
	<dependencies>
		<!-- Spring框架 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>4.3.14.RELEASE</version>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<!-- jdk1.8 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>
		</plugins>
		<finalName>spr</finalName>
	</build>
</project>

定义对应的类,并进行配置,将对象纳入到容器中进行管理(使用Date)

<?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="now" class="java.util.Date" />
	
	<!-- id,name命名比较随意,一般按照java变量命名规则 -->
	<bean id="123d" name="555" class="java.util.Date" scope="prototype" />
	
	<bean id="df" class="java.text.SimpleDateFormat" >
		<!-- 自定义日期格式,通过反射,必须要有无参构造方法 -->
		<constructor-arg value="yyyy-MM-dd" />
	</bean>
</beans>

获取IoC容器的引用

package spr;

import java.text.DateFormat;
import java.util.Date;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

@SuppressWarnings("deprecation")
public class Test_01 {
	public static void main(String[] args) {
		// 获取IoC容器的引用
		Resource r = new ClassPathResource("applicationContext.xml");
		
		// 获取工程
		BeanFactory fac = new XmlBeanFactory(r);
		
		// 从IoC容器中通过名称获取配置在IoC容器中的受管bean
		Date dd = (Date) fac.getBean("now");
		DateFormat df = (DateFormat) fac.getBean("df");
		
		// 调用受管bean对象的方法完成业务逻辑处理
		System.out.println(df.format(dd));
	}
}

4.ApplicationContext

上面的代码中可以看到,XmlBeanFactory已被废弃

不建议使用,所以,建议使用ApplicationContext

package spr;

import java.text.DateFormat;
import java.util.Date;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test_01 {
	public static void main(String[] args) {
		// 获取IoC容器的引用
		ApplicationContext fac = new ClassPathXmlApplicationContext("applicationContext.xml");
		
		// 从IoC容器中通过名称获取配置在IoC容器中的受管bean
		Date dd = fac.getBean("555", Date.class);
		DateFormat df = (DateFormat) fac.getBean("df");
		
		// 调用受管bean对象的方法完成业务逻辑处理
		System.out.println(df.format(dd));
	}
}
ApplicationContext接口继承于BeanFactory接口

主要用于引用IoC/DI容器

ApplicationContext具有BeanFactory的所有功能

另外提供针对企业级开发的功能支持

5.getBean(Class<T>)

T在IoC容器中按照类型查找所有的受管bean对象

如果一个类型有2个受管配置(id重复),则按类型查找出错

NoUniqueBeanDefinitionException

6.T getBean(String受管bean名称, Class<T>目标类型)

返回以给定名称注册的Bean,返回的Bean将被cast给定的类

如Bean不能被Cast,异常BeanNotOfRequiredTypeException将被抛出

Date dd = fac.getBean("555", Date.class)

7.其他不重要的方法

boolean containsBean(String受管bean的名称):

如果BeanFactory包含符合给定名称的Bean定义或Bean实例,则返回true

Class getType(String name受管bean的名称):

返回给定名称的Bean的 Class

如果对应的Bean找不到,则会抛出NoSuchBeanDefinitionException异常

boolean isSingleton(String):

决定在给定名称时,Bean定义或Bean实例注册是否为单例模式

如果对应的Bean不能被找到,则抛出异常

String[] getAliases(String):

如果在Bean的定义中有定义,则返回给定Bean名称的别名

8.配置文件中的命名规则

在配置文件中使用id属性定义受管bean的名称

一般建议采用Java变量的命名规则,实际上使用123d或者12,3d都是可以的

需要注意Spring版本的区别,id只能定义一个名称

如果需要定义多个可以使用name属性进行定义

这里使用id、name名称都可以获取受管bean

针对获取受管bean对象的名称而言,其它的名称都叫做别名

Id命名建议采用Java变量的命名机制

注意Spring3-id命名规范比较严格

Spring3+命名中允许数字开头,允许使用包括空格在内的特殊符号

但是注意的是id只有一个名字,name允许使用特殊符号,是多个名称

id命名中空格是名称的一部分,name可以使用空格或者逗号分隔多个名称

<bean id="123d" name="/dd.do 555" class="java.util.Date" />

9.受管bean

受管bean就是纳入到IoC/DI容器中,由容器负责创建和管理生命周期的javabean对象

Xml配置受管bean   applicationContext.xml

<bean

id=”受管bean的标识符,唯一,这里只能定义一个名称”

class=”受管bean类的全名”

name=”别名,可以定义多个,使用逗号分隔”

scope=”范围,可以设置,默认singleton单例

[Spring容器默认提供了单例模式的实现,不需要编码]

prototype原型,每次获取的都是新建的对象

另外还有和web相关的3个配置request、session、global session”/>

受管bean的要求:一般来说任何java类都可以作为受管bean

Spring中那些组成应用的主体以及由Spring IoC容器所管理的对象被称之为bean

Bean就是由Spring容器初始化、装配以及被管理的对象

bean是Spring管理的基本单位,在Spring的应用中

所有的组件都是bean,bean包括数据源,Hibernate的SessionFactory及事务管理器等

Spring里的bean是非常广义的概念,任何的Java对象

Java组件都可被当成bean处理,甚至这些组件并不是标准的JavaBean

10.BeanFactory和ApplicationContext的关系

BeanFacotry是spring中比较原始的Factory,提供了IoC/DI容器使用的最基本的方法

ApplicationContext接口由BeanFactory接口派生而来

在提供BeanFactory所有的功能基础上提供了企业级应用开发的支持

例如读取资源文件、发布事件等

BeanFactory针对单例的受管bean采用的是延迟加载

ApplicationContext采用的是立即加载【所有的prototype受管bean都是延迟】

所以BeanFactory一般用于内存敏感的受限环境开发中,ApplicationContext一般使用

11.4大原则

使用POJO进行轻量级和最小侵入式开发

POJO(Plain Ordinary Java Object)简单的Java对象

实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称

通过控制反转IoC、依赖注入DI和基于接口编程实现松耦合

通过AOP和默认惯例进行声明式编程

使用AOP和模板编程减少模式化代码

12.主要功能

基于Java Beans的配置管理,采用IOC的原理,特别是对依赖注射技术的使用

这些都用来减少各组件间对实施细则的相互依赖性

一个核心的,全局适用的bean工厂

一个一般抽象化的层面来管理数据库间的数据处理

建立在框架内的,对Java数据处理API和单独的JDBC数据源的一般性策略

因此,在数据处理支持上对Java企业版本环境的依赖性得以消除

和一些整合持久化的框架,如Hibernate,JDO,iBATIS和db4o,的整合

web应用中的MVC框架,基于核心的Spring功能,支持多种产生视图的技术

包括JSP,FreeMarker,Velocity,Tiles,iText,和POI

大量的AOP框架以提供诸如数据处理管理的服务

同IOC的功能一样,目的是提高系统的模块化程度

13.基本框架结构

Spring是一种JavaEE开发中的一站式解决方案,所以其中包含的内容比较多

为了避免在应用中添加无用功能,所以Spring采用了非强制性的模块化结构

在具体应用中,可以根据应用所需要的功能进行选择添加

a.Spring3.x分为6大模块,Spring的模块化是很强的

各个功能模块都是独立的,可以选择的使用


Core模块是Spring应用的基础,提供了最基本的IoC/DI容器的支持和实现

AOP模块建立在Core模块的基础上,提供了AOP技术的支持

以简化AOP编程的复杂度

DAO和ORM模块建立在AOP的基础上

DAO提供了dao模式编程的简化支持,ORM提供了整合持久层框架的支持

同时在AOP的基础上给数据库访问提供了声明式事务的支持

JEE模块建立在Core模块的基础上

提供了针对EJB\邮件javaMail等企业级应用支持

Web模块建立在core模块的基础上

提供了整合其它表现层框架【例如Struts\JSF等】的支持

同时提出了自己的表现层框架SpringMVC[针对Struts1提出的]

b.Spring4.x分为6大模块,包括20多个子项目


Core container核心容器:beans core context context-support expression

AOP和apects提供AOP编程技术支持:

aop aspects,另外还有其它的不是Spring的jar

Data Access/Integration针对DAO编程和ORM整合的支持: jdbc orm tx

Web提供了整合表现层框架和对应的web解决方案SpringMVC:web webmvc

Instrumentation底层基础,是一种没有图形界面的

具有启动能力的,用于监控其他类的工具类

Test提供了单元测试的支持,要求junit4.8+版本

14.Spring的全方位应用程序框架


ssm=SpringMVC+Spring+MyBatis

[一般开发中常用,尤其是互联网应用开发类型的公司,一般中小型快速开发中应用]

ssh[2]=Struts2+Spring+Hibernate 

[使用较少,一般在大型软件公司中长期使用]

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值