全网疯传的Spring学习笔记,看完我也想写一个了!
一、工厂设计模式
1.1、传统的容器——EJB的缺点
EJB(Enterprise Java Beans),被称为企业Java Beans。他是上一代使用的容器。我们来看看传统的J2EE的体系。
EJB具有的缺点是很致命的:
- 运行环境苛刻。
- 代码移植性很差。
- EJB是重量级框架。
1.2、什么是Spring
Spring是一个轻量级的JavaEE解决方案,整合众多优秀的设计模式,其中最重要的设计模式是——工厂设计模式。他还包含其他的设计模式,比如说:代理设计模式、模板设计模式、策略设计模式等等。
1.3、什么是工厂设计模式
在传统的创建对象的时候,我们都是调用无参构造函数来创建对象的即new的方式来创建,这样创建对象的方式的耦合程度(指定是代码间的强关联关系,一方的改变会影响到另一方)就十分高。、
一旦我们需要修改类型,就需要代码中修改,并且重新编译和部署。
1.4、工厂设计模式的实现
package com.factory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class BeanFactory {
private static Properties env = new Properties();
static{
try {
//第一步 获得IO输入流
InputStream inputStream = BeanFactory.class.getResourceAsStream("/applicationContext.properties");
//第二步 文件内容 封装 Properties集合中 key = userService ,value = com.service.impl.UserServiceImpl
env.load(inputStream);
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/*
对象的创建的两种方式:
1. 直接调用构造方法创建对象 UserService userService = new UserServiceImpl();
2. 通过反射的形式创建对象可以解耦合
Class clazz = Class.forName("com.service.impl.UserServiceImpl");
UserService userService = (UserService)clazz.newInstance();
*/
public static UserService getUserService() {
UserService userService = null;
try {
Class clazz = Class.forName(env.getProperty("userService"));
userService = (UserService) clazz.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return userService;
}
public static UserDAO getUserDAO(){
UserDAO userDAO = null;
try {
Class clazz = Class.forName(env.getProperty("userDAO"));
userDAO = (UserDAO) clazz.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return userDAO;
}
}
userDAO = com.dao.userDAO
userService = com.service.userService
1.5、简单工厂的代码修改
我们可以发现,上面一个工厂设计模式的代码是又臭又长,我们每创建一个新的对象,都需要重新写一个工厂类,并且代码很大一部分都是相同的,仅仅只是创建的对象不同,于是我们可以抽取出共同的代码,组成一个通用的工厂类。
public class BeanFactory{
public static Object getBean(String key){
Object ret = null;
try {
Class clazz = Class.forName(env.getProperty(key));
ret = clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
}
1.6、总结
Spring本质上就是一个工厂,只不过我们在日常开发的时候使用的不是自己写的工厂,因为这个工厂的功能很少,性能很低下,Spring帮我们写好了一个大型工厂(ApplicationContext),我们只需要在一个固定的配置文件(applicationContext.xml)中进行配置即可。
二、Spring入门
2.1、Spring简介
Spring 是于 2003 年兴起的一个轻量级的 Java 开发框架,它是为了解决企业应用开发的复杂性而创建的。Spring 的核心是控制反转(IoC)和面向切面编程(AOP)。Spring 是可以在 Java SE/EE 中使用的轻量级开源框架。
Spring 的主要作用就是为代码“解耦”,降低代码间的耦合度。就是让对象和对象(模块和模块)之间关系不是使用代码关联,而是通过配置来说明。即在 Spring 中说明对象(模块)的关系。
Spring 根据代码的功能特点,使用 Ioc 降低业务对象之间耦合度。IoC 使得主业务在相互调用过程中,不用再自己维护关系了,即不用再自己创建要使用的对象了。而是由 Spring容器统一管理,自动“注入”,注入即赋值。 而 AOP 使得系统级服务得到了最大复用,且不用再由程序员手工将系统级服务“混杂”到主业务逻辑中了,而是由 Spring 容器统一完成“织入”。
2.2、Spring的优点
Spring 是一个框架,是一个半成品的软件。由 20 个模块组成。它是一个容器管理对象,容器是装东西的,Spring 容器不装文本,数字。装的是对象。Spring 是存储对象的容器。他的优点主要是以下几个方面。
- 轻量。
- 面向接口编程。
- 面向切面编程
- 可以轻易集成其他优秀的框架。
2.2.1、轻量
Spring 框架使用的 jar 都比较小,一般在 1M 以下或者几百 kb。Spring 核心功能的所需的 jar 总共在 3M 左右。
Spring 框架运行占用的资源少,运行效率高。不依赖其他 jar。
2.2.2、面向接口编程
Spring 提供了 Ioc 控制反转,由容器管理对象,对象的依赖关系。原来在程序代码中的对象创建方式,现在由容器完成。对象之间的依赖解耦合。
2.2.3、面向切面编程(AOP)
通过 Spring 提供的 AOP 功能,方便进行面向切面的编程,许多不容易用传统 OOP 实现的功能可以通过 AOP 轻松应付。
在 Spring 中,开发人员可以从繁杂的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。
2.2.4、集成其他优秀的框架
Spring 不排斥各种优秀的开源框架,相反 Spring 可以降低各种框架的使用难度,Spring提供了对各种优秀框架(如 Shiro、MyBatis)等的直接支持。简化框架的使用。
Spring 像插线板一样,其他框架是插头,可以容易的组合到一起。需要使用哪个框架,就把这个插头放入插线板。不需要可以轻易的移除。
2.3、Spring的体系结构
Spring 由 20 多个模块组成,它们可以分为数据访问/集成(Data Access/Integration)、Web、面向切面编程(AOP, Aspects)、提供 JVM的代理(Instrumentation)、消息发送(Messaging)、核心容器(Core Container)和测试(Test)。
2.4、Spring的核心API
Spring的核心就是一个大工厂:ApplicationContext,他的作用是用于对象的创建,且可以解除耦合,他是一个接口,但是ApplicationContext是一个重量级的工厂对象占用大量的内存,所以我们不会频繁得去创建对象,一般一个应用只会创建一个工厂对象。ApplicationContext是线程安全的,可以被多线程并发访问。
他有两种实现方式:
- 适用于非WEB环境的:ClassPathXmlApplication
- 适用于WEB环境的:XmlApplicationContext
2.5、Spring的案例
2.5.1、引入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
2.5.3、创建类型
package com.domain;
/**
* @author Xiao_Lin
* @date 2021/2/4 15:57
*/
public class Person {
}
2.5.4、修改配置文件
在applicationContext.xml的配置文件中更改配置
<!-- id属性:名字-->
<!-- class属性:需要创建对象的全限定名-->
<bean id="person" class="com.domain.Person"/>
2.5.5、创建对象
/**
* 用于测试Spring的第一个程序
*/
@Test
public void testSpring(){
// 1. 获得Spring的工厂
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/applicationContext.xml");
// 2. 通过工厂类来获得对象
Person person = (Person)applicationContext.getBean("person");
System.out.println(person);
}
2.6、细节分析
2.6.1、名词解释
Spring工厂创建的对象,叫做bean或者组件(componet)
2.6.2、相关方法
//通过这种方式获得对象,就不需要强制类型转换
Person person = ctx.getBean("person", Person.class);
System.out.println("person = " + person);
//当前Spring的配置文件中 只能有一个<bean>标签的class是Person类型
Person person = ctx.getBean(Person.class);
System.out.println("person = " + person);
//获取的是 Spring工厂配置文件中所有bean标签的id值 person person1
String[] beanDefinitionNames = ctx.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println("beanDefinitionName = " + beanDefinitionName);
}
//根据类型获得Spring配置文件中对应的id值
String[] beanNamesForType = ctx.getBeanNamesForType(Person.class);
for (String id : beanNamesForType) {
System.out.println("id = " + id);
}
//用于判断是否存在指定id值的bean
if (ctx.containsBeanDefinition("a")) {
System.out.println("true = " + true);
}else{
System.out.println("false = " + false);
}
//用于判断是否存在指定id(name)值的bean
if (ctx.containsBean("person")) {
System.out.println("true = " + true);
}else{
System.out.println("false = " + false);
}
2.7、Spring创建对象的简易原理图
注意:反射底层调用的是无参构造函数来进行实例化对象的,即使构造方法私有了,依然可以调用进行实例化对象。
2.8、注意
在未来开发的过程中,理论上所有的对象都是交给Spring工厂来创建,但是有一类特殊的对象——实体对象是不会交给Spring来创建的,它是交给持久层来创建的。
- 点赞
- 收藏
- 关注作者
评论(0)