Spring概述

简介

Spring : 春天 —>给软件行业带来了春天

2002年,Rod Jahnson首次推出了Spring框架雏形interface21框架。

2004年3月24日,Spring框架以interface21框架为基础,经过重新设计,发布了1.0正式版。

很难想象Rod Johnson的学历 , 他是悉尼大学的博士,然而他的专业不是计算机,而是音乐学。

Spring理念 : 使现有技术更加实用 . 本身就是一个大杂烩 , 整合现有的框架技术

官网 : http://spring.io/

官方下载地址 : https://repo.spring.io/libs-release-local/org/springframework/spring/

GitHub : https://github.com/spring-projects

优点

1、Spring是一个开源免费的框架 , 容器 .

2、Spring是一个轻量级的框架 , 非侵入式的 .

3、控制反转 IoC , 面向切面 Aop

4、对事物的支持 , 对框架的支持

一句话概括:

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架)。

组成

Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式 。

组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:

  • 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转(IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
  • Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
  • Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能 , 集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理任何支持 AOP的对象。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖组件,就可以将声明性事务管理集成到应用程序中。
  • Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
  • Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
  • Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
  • Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

拓展

Spring Boot与Spring Cloud

  • Spring Boot 是 Spring 的一套快速配置脚手架,可以基于Spring Boot 快速开发单个微服务;
  • Spring Cloud是基于Spring Boot实现的;
  • Spring Boot专注于快速、方便集成的单个微服务个体,Spring Cloud关注全局的服务治理框架;
  • Spring Boot使用了约束优于配置的理念,很多集成方案已经帮你选择好了,能不配置就不配置 , Spring Cloud很大的一部分是基于Spring Boot来实现,Spring Boot可以离开Spring Cloud独立使用开发项目,但是Spring Cloud离不开Spring Boot,属于依赖的关系。
  • SpringBoot在SpringClound中起到了承上启下的作用,如果你要学习SpringCloud必须要学习SpringBoot。

IOC理论推导

IoC基础

新建一个空白的maven项目

分析实现

我们先用我们原来的方式写一段代码 .

1、先写一个UserDao接口

public interface UserDao {public void getUser();
}

2、再去写Dao的实现类

public class UserDaoImpl implements UserDao {@Overridepublic void getUser() {System.out.println("获取用户数据");}
}

3、然后去写UserService的接口

public interface UserService {public void getUser();
}

4、最后写Service的实现类

public class UserServiceImpl implements UserService {private UserDao userDao = new UserDaoImpl();@Overridepublic void getUser() {userDao.getUser();}
}

5、测试一下

@Test
public void test(){UserService service = new UserServiceImpl();service.getUser();
}

这是我们原来的方式 , 开始大家也都是这么去写的对吧 . 那我们现在修改一下 .

把Userdao的实现类增加一个 .

public class UserDaoMySqlImpl implements UserDao {@Overridepublic void getUser() {System.out.println("MySql获取用户数据");}
}

紧接着我们要去使用MySql的话 , 我们就需要去service实现类里面修改对应的实现

public class UserServiceImpl implements UserService {private UserDao userDao = new UserDaoMySqlImpl();@Overridepublic void getUser() {userDao.getUser();}
}

在假设, 我们再增加一个Userdao的实现类 .

public class UserDaoOracleImpl implements UserDao {@Overridepublic void getUser() {System.out.println("Oracle获取用户数据");}
}

那么我们要使用Oracle , 又需要去service实现类里面修改对应的实现 . 假设我们的这种需求非常大 , 这种方式就根本不适用了, 甚至反人类对吧 , 每次变动 , 都需要修改大量代码 . 这种设计的耦合性太高了, 牵一发而动全身 .

那我们如何去解决呢 ?

我们可以在需要用到他的地方 , 不去实现它 , 而是留出一个接口 , 利用set , 我们去代码里修改下 .

public class UserServiceImpl implements UserService {private UserDao userDao;
// 利用set实现public void setUserDao(UserDao userDao) {this.userDao = userDao;}@Overridepublic void getUser() {userDao.getUser();}
}

现在去我们的测试类里 , 进行测试 ;

@Test
public void test(){UserServiceImpl service = new UserServiceImpl();service.setUserDao( new UserDaoMySqlImpl() );service.getUser();//那我们现在又想用Oracle去实现呢service.setUserDao( new UserDaoOracleImpl() );service.getUser();
}

大家发现了区别没有 ? 可能很多人说没啥区别 . 但是同学们 , 他们已经发生了根本性的变化 , 很多地方都不一样了 . 仔细去思考一下 , 以前所有东西都是由程序去进行控制创建 , 而现在是由我们自行控制创建对象 , 把主动权交给了调用者 . 程序不用去管怎么创建,怎么实现了 . 它只负责提供一个接口 .

这种思想 , 从本质上解决了问题 , 我们程序员不再去管理对象的创建了 , 更多的去关注业务的实现 . 耦合性大大降低 . 这也就是IOC的原型 !

IOC本质

控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IOC的一种方法,也有人认为DI只是IOC的另一种说法。没有IOC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。

IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC。

Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。

采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。

依赖注入(DI)

概念

  • 依赖注入(Dependency Injection,DI)。
  • 依赖 : 指Bean对象的创建依赖于容器 . Bean对象的依赖资源 .
  • 注入 : 指Bean对象所依赖的资源 , 由容器来设置和装配 .

构造器注入

我们在之前的案例已经讲过了

Set 注入 (重点)

要求被注入的属性 , 必须有set方法 , set方法的方法名由set + 属性首字母大写 , 如果属性是boolean类型 , 没有set方法 , 是 is .

测试pojo类 :

Address.java

 public class Address {private String address;public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}}

Student.java

 package com.kuang.pojo;import java.util.List;import java.util.Map;import java.util.Properties;import java.util.Set;public class Student {private String name;private Address address;private String[] books;private List<String> hobbys;private Map<String,String> card;private Set<String> games;private String wife;private Properties info;public void setName(String name) {this.name = name;}public void setAddress(Address address) {this.address = address;}public void setBooks(String[] books) {this.books = books;}public void setHobbys(List<String> hobbys) {this.hobbys = hobbys;}public void setCard(Map<String, String> card) {this.card = card;}public void setGames(Set<String> games) {this.games = games;}public void setWife(String wife) {this.wife = wife;}public void setInfo(Properties info) {this.info = info;}public void show(){System.out.println("name="+ name+ ",address="+ address.getAddress()+ ",books=");for (String book:books){System.out.print("<<"+book+">>\t");}System.out.println("\n爱好:"+hobbys);System.out.println("card:"+card);System.out.println("games:"+games);System.out.println("wife:"+wife);System.out.println("info:"+info);}}

1、常量注入

 <bean id="student" class="com.kuang.pojo.Student"><property name="name" value="小明"/></bean>

测试:

 @Testpublic void test01(){ApplicationContext context = newClassPathXmlApplicationContext("applicationContext.xml");Student student = (Student) context.getBean("student");System.out.println(student.getName());}

2、Bean注入

注意点:这里的值是一个引用,ref

 <bean id="addr" class="com.kuang.pojo.Address"><property name="address" value="重庆"/></bean><bean id="student" class="com.kuang.pojo.Student"><property name="name" value="小明"/><property name="address" ref="addr"/></bean>

3、数组注入

 <bean id="student" class="com.kuang.pojo.Student"><property name="name" value="小明"/><property name="address" ref="addr"/><property name="books"><array><value>西游记</value><value>红楼梦</value><value>水浒传</value></array></property></bean>

4、List注入

 <property name="hobbys"><list><value>听歌</value><value>看电影</value><value>爬山</value></list></property>

5、Map注入

 <property name="card"><map><entry key="中国邮政" value="456456456465456"/><entry key="建设" value="1456682255511"/></map></property>

6、set注入

 <property name="games"><set><value>LOL</value><value>BOB</value><value>COC</value></set></property>

7、Null注入

 <property name="wife"><null/></property>

8、Properties注入

 <property name="info"><props><prop key="学号">20190604</prop><prop key="性别">男</prop><prop key="姓名">小明</prop></props></property>

测试结果:

p命名和c命名注入

User.java :【注意:这里没有有参构造器!】

 public class User {private String name;private int age;public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}}

1、P命名空间注入 : 需要在头文件中加入约束文件 (实体类中要有无参构造器)

 导入约束 : xmlns:p="http://www.springframework.org/schema/p"<!--P(属性: properties)命名空间 , 属性依然要设置set方法--><bean id="user" class="com.kuang.pojo.User" p:name="狂神" p:age="18"/>

2、c 命名空间注入 : 需要在头文件中加入约束文件(在实体类中要有有参构造)

 导入约束 : xmlns:c="http://www.springframework.org/schema/c"<!--C(构造: Constructor)命名空间 , 属性依然要设置set方法--><bean id="user" class="com.kuang.pojo.User" c:name="狂神" c:age="18"/>

发现问题:爆红了,刚才我们没有写有参构造!

解决:把有参构造器加上,这里也能知道,c 就是所谓的构造器注入!

测试代码:

 @Testpublic void test02(){ApplicationContext context = newClassPathXmlApplicationContext("applicationContext.xml");User user = (User) context.getBean("user");System.out.println(user);}

Bean的创建方式:

1.构造方法实例化

2.静态工厂实例化:在类中创建public static 方法,然后再xml中配置id,class,factory_method

3.实例工厂实例化:在类中创建普通方法,里面返回new 类名,然后再xml中配置id,class,bean id(方法名),factory_bean(上面的第一个id),factory_method

后序还有Spring的相关文章!

Spring系列 1.Spring概述及IOP相关推荐

  1. Spring系列之Spring框架和SpringAOP集成过程分析(十)

    转载请注明出处:https://blog.csdn.net/zknxx/article/details/80724180 在开始这个系列之前大家先想一下我们是怎么在项目中使用SpringAOP的(这里 ...

  2. Spring系列之Spring Web MVC-20

    目录 Spring Web MVC DispatcherServlet 上下文层次结构 特殊Bean Web MVC 配置 程序配置 工作原理 异常 视图解析 配置 重定向 转发 内容协商 过滤器 F ...

  3. Spring系列之Spring常用注解总结

    参看博客:https://www.cnblogs.com/xiaoxi/p/5935009.html 传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺 ...

  4. 【Spring 系列】Spring知识地图

    文章目录 Spring IOC 知道 会用 熟练 掌握 专家 Spring AOP 知道 会用 熟练 掌握 专家 Spring MVC 知道 会用 熟练 掌握 专家 Spring WebFlux 知道 ...

  5. Spring系列之Spring常用注解总结 原文:https://www.cnblogs.com/xiaoxi/p/5935009.html

    传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点: 1.如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大:如果按需求分开.xml文 ...

  6. Spring系列之一 Spring MVC

    摘要: 最近在看Spring的书,之前一直跟着项目做,虽然项目用到了Spring的很多功能,但是我很少有机会在工作的项目中去配置Spring.感觉只有理论是不够的,虽然只是用Spring的配置让人感觉 ...

  7. Spring系列(六) Spring Web MVC 应用构建分析

    DispatcherServlet DispatcherServlet 是Spring MVC的前端控制器名称, 用户的请求到达这里进行集中处理, 在Spring MVC中, 它的作用是为不同请求匹配 ...

  8. 【Spring系列】- Spring循环依赖

    Spring循环依赖

  9. 【Spring系列】 Spring注解方式实现IOC、DI及其Spring其他注解

    文章目录 注解回顾 JDK内置注解 自定义注解 1.声明一个注解类,由`@interface`修饰 2.通过元注解修饰注解的定义 `@Target`:(常用) `@Retention`:(常用) `@ ...

最新文章

  1. 「NLP」ALBERT:更轻更快的NLP预训练模型
  2. python自动化脚本实例100条-自动化运维基础实例解析-Python批量登录到服务器执行任务...
  3. Android中通过Java代码实现ScrollView滚动视图-以歌词滚动为例
  4. QT的QMessageAuthenticationCode类的使用
  5. 5个必须掌握的maven命令
  6. java 8 io_Java IO8:IO简单总结
  7. DevOps 能力提升模型
  8. (11)FPGA面试题同步复位与异步复位
  9. 安装完centos6没有eth0,只有回环地址
  10. 百度服务器临时文件多久一删,百度站长提醒:11月9日前尽快删除超出站点配额的历史sitemap文件...
  11. CIF、DCIF、D1分辨率是多少?
  12. silklabo哪个公众号有资源_公众号和头条号,做哪个赚钱?
  13. 用python画小仓鼠教程_小仓鼠简笔画教程
  14. 分数化成有限小数的方法_怎样把分数化成小数
  15. 使用gcc编译报错:/tmp/ccoLTk4o.o:在函数‘main’中: main1.c:(.text+0x9c):对‘pirnt1’未定义的引用 collect2: 错误:ld 返回 1
  16. 原来路由器的USB接口这么强大!这样设置,路由器秒变私有云盘
  17. macOS必备APP macOS 下那些鲜为人知的使用技巧
  18. C++ 共享指针四宗罪
  19. pkg打包node服务为双击可执行二进制文件Windows x64系统
  20. 携旅:大数据推进新旅游住宿发展

热门文章

  1. Tomcat的启动与停止
  2. 【新概念4】【6】the sporting spirit
  3. 十大建立网站的开源程序
  4. cgb2110-day10
  5. 网站导航栏SEO优化方法
  6. 工作中的自我反思[实时更新]
  7. 科技周刊第六期:接近本质的东西才会长远
  8. 第28章 LTDC—液晶显示中英文—零死角玩转STM32-F429系列
  9. MVC与MVVC的区别
  10. 微软开源Citus企业版全部功能:提供分布式Postgres数据库功能