谈谈对 Spring 的理解

认识 Spring 框架

Spring 框架是 Java 应用最广的框架,它的成功来源于理念,而不是技术本身,它的理念包括 IoC (Inversion of Control,控制反转)AOP(Aspect Oriented Programming,面向切面编程)

什么是 Spring:

  1. Spring 是一个轻量级的 DI / IoC 和 AOP 容器的开源框架,来源于 Rod Johnson 在其著作**《Expert one on one J2EE design and development》**中阐述的部分理念和原型衍生而来。
  2. Spring 提倡以**“最少侵入”**的方式来管理应用中的代码,这意味着我们可以随时安装或者卸载 Spring
  • 适用范围:任何 Java 应用
  • Spring 的根本使命:简化 Java 开发

尽管 J2EE 能够赶上 Spring 的步伐,但 Spring 并没有停止前进, Spring 继续在其他领域发展,而 J2EE 则刚刚开始涉及这些领域,或者还没有完全开始在这些领域的创新。移动开发、社交 API 集成、NoSQL 数据库、云计算以及大数据都是 Spring 正在涉足和创新的领域。Spring 的前景依然会很美好。

Spring 中常用术语:

  • 框架:是能完成一定功能半成品
    框架能够帮助我们完成的是:项目的整体框架、一些基础功能、规定了类和对象如何创建,如何协作等,当我们开发一个项目时,框架帮助我们完成了一部分功能,我们自己再完成一部分,那这个项目就完成了。
  • 非侵入式设计:
    从框架的角度可以理解为:无需继承框架提供的任何类
    这样我们在更换框架时,之前写过的代码几乎可以继续使用。
  • 轻量级和重量级:
    轻量级是相对于重量级而言的,轻量级一般就是非入侵性的、所依赖的东西非常少、资源占用非常少、部署简单等等,其实就是比较容易使用,而重量级正好相反
  • JavaBean:
    符合 JavaBean 规范的 Java 类
  • POJO:Plain Old Java Objects,简单老式 Java 对象
    它可以包含业务逻辑或持久化逻辑,但
    不担当任何特殊角色
    不继承或不实现任何其它Java框架的类或接口。

注意:bean 的各种名称——虽然 Spring 用 bean 或者 JavaBean 来表示应用组件,但并不意味着 Spring 组件必须遵循 JavaBean 规范,一个 Spring 组件可以是任意形式的 POJO。

  • 容器:
    在日常生活中容器就是一种盛放东西的器具,从程序设计角度看就是装对象的的对象,因为存在放入、拿出等操作,所以容器还要管理对象的生命周期

Spring 的优势

  • 低侵入 / 低耦合 (降低组件之间的耦合度,实现软件各层之间的解耦)
  • 声明式事务管理(基于切面和惯例)
  • 方便集成其他框架(如MyBatis、Hibernate)
  • 降低 Java 开发难度
  • Spring 框架中包括了 J2EE 三层的每一层的解决方案(一站式)

Spring 能帮我们做什么

①.Spring 能帮我们根据配置文件创建及组装对象之间的依赖关系
②.Spring 面向切面编程能帮助我们无耦合的实现日志记录,性能统计,安全控制。
③.Spring非常简单的帮我们管理数据库事务
④.Spring提供了与第三方数据访问框架(如Hibernate、JPA)无缝集成,而且自己也提供了一套JDBC访问模板来方便数据库访问。
⑤.Spring 还提供与第三方Web(如Struts1/2、JSF)框架无缝集成,而且自己也提供了一套Spring MVC框架,来方便web层搭建。
⑥.Spring方便的与Java EE(如Java Mail、任务调度)整合,与更多技术整合(比如缓存框架)

Spring 的框架结构

img

  • Data Access/Integration层包含有JDBC、ORM、OXM、JMS和Transaction模块。
  • Web层包含了Web、Web-Servlet、WebSocket、Web-Porlet模块。
  • AOP模块提供了一个符合AOP联盟标准的面向切面编程的实现。
  • **Core Container(核心容器):**包含有Beans、Core、Context和SpEL模块。
  • Test模块支持使用JUnit和TestNG对Spring组件进行测试。

Spring IoC 和 DI 简介

IoC:Inverse of Control(控制反转)

  • 读作**“反转控制”,更好理解,不是什么技术,而是一种设计思想**,就是将原本在程序中手动创建对象的控制权,交由Spring框架来管理。
  • 正控:若要使用某个对象,需要自己去负责对象的创建
  • 反控:若要使用某个对象,只需要从 Spring 容器中获取需要使用的对象,不关心对象的创建过程,也就是把创建对象的控制权反转给了Spring框架
  • **好莱坞法则:**Don’t call me ,I’ll call you

一个例子

控制反转显然是一个抽象的概念,我们举一个鲜明的例子来说明。

在现实生活中,人们要用到一样东西的时候,第一反应就是去找到这件东西,比如想喝新鲜橙汁,在没有饮品店的日子里,最直观的做法就是:买果汁机、买橙子,然后准备开水。值得注意的是:这些都是你自己**“主动”创造**的过程,也就是说一杯橙汁需要你自己创造。

img

然而到了今时今日,由于饮品店的盛行,当我们想喝橙汁时,第一想法就转换成了找到饮品店的联系方式,通过电话等渠道描述你的需要、地址、联系方式等,下订单等待,过一会儿就会有人送来橙汁了。

img

请注意你并没有“主动”去创造橙汁,橙汁是由饮品店创造的,而不是你,然而也完全达到了你的要求,甚至比你创造的要好上那么一些。

编写第一个 Spring 程序

  1. 新建一个空的 Java 项目,命名为【spring】

  2. 新建一个名为【lib】的目录,并添加进必要的 jar 包,导入项目

  3. 在 Packge【pojo】下新建一个【Source】类:

package pojo;public class Source {  private String fruit;   // 类型private String sugar;   // 糖分描述private String size;    // 大小杯    /* setter and getter */
}
  1. 在 【src】 目录下新建一个 【applicationContext.xml】 文件,通过 xml 文件配置的方式装配我们的 bean
<?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 name="source" class="pojo.Source"><property name="fruit" value="橙子"/><property name="sugar" value="多糖"/><property name="size" value="超大杯"/></bean>
</beans>
  1. 在 Packge【test】下新建一个【TestSpring】类:
package test;import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import pojo.Source;public class TestSpring {@Testpublic void test(){ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});Source source = (Source) context.getBean("source");System.out.println(source.getFruit());System.out.println(source.getSugar());System.out.println(source.getSize());}
}
  1. 运行测试代码,可以正常拿到 xml 配置的 bean

总结:

  • 传统的方式:
    通过new 关键字主动创建一个对象
  • IOC方式:
    对象的生命周期由Spring来管理,直接从Spring那里去获取一个对象。 IOC是反转控制 (Inversion Of Control)的缩写,就像控制权从本来在自己手里,交给了Spring。

DI:Dependency Injection(依赖注入)

  • 指 Spring 创建对象的过程中,将对象依赖属性(简单值,集合,对象)通过配置设值给该对象

继续上面的例子

  1. 在 Packge【pojo】下新建一个【JuiceMaker】类:
package pojo;public class JuiceMaker {// 唯一关联了一个 Source 对象private Source source = null;/* setter and getter */public String makeJuice(){String juice = "xxx用户点了一杯" + source.getFruit() + source.getSugar() + source.getSize();return juice;}
}
  1. 在 xml 文件中配置 JuiceMaker 对象:
  • 注意:这里要使用 ref 来注入另一个对象
<?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 name="source" class="pojo.Source"><property name="fruit" value="橙子"/><property name="sugar" value="多糖"/><property name="size" value="超大杯"/></bean><bean name="juickMaker" class="pojo.JuiceMaker"><property name="source" ref="source" /></bean>
</beans>
  1. 在 【TestSpring】 中添加如下代码:
package test;import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import pojo.JuiceMaker;
import pojo.Source;public class TestSpring {@Testpublic void test(){ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});Source source = (Source) context.getBean("source");System.out.println(source.getFruit());System.out.println(source.getSugar());System.out.println(source.getSize());JuiceMaker juiceMaker = (JuiceMaker) context.getBean("juickMaker");System.out.println(juiceMaker.makeJuice());}
}
  1. 运行测试代码

总结:IoC 和 DI 其实是同一个概念的不同角度描述,DI 相对 IoC 而言,明确描述了“被注入对象依赖 IoC 容器配置依赖对象”

IoC 如何实现的

最后我们简单说说IoC是如何实现的。想象一下如果我们自己来实现这个依赖注入的功能,我们怎么来做? 无外乎:

  1. 读取标注或者配置文件,看看JuiceMaker依赖的是哪个Source,拿到类名
  2. 使用反射的API,基于类名实例化对应的对象实例
  3. 将对象实例,通过构造函数或者 setter,传递给 JuiceMaker

我们发现其实自己来实现也不是很难,Spring实际也就是这么做的。这么看的话其实IoC就是一个工厂模式的升级版!当然要做一个成熟的IoC框架,还是非常多细致的工作要做,Spring不仅提供了一个已经成为业界标准的Java IoC框架,还提供了更多强大的功能,所以大家就别去造轮子啦!希望了解IoC更多实现细节不妨通过学习Spring的源码来加深理解!


Spring AOP 简介

如果说 IoC 是 Spring 的核心,那么面向切面编程就是 Spring 最为重要的功能之一了,在数据库事务中切面编程被广泛使用。

AOP 即 Aspect Oriented Program 面向切面编程

首先,在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能。

  • 所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务
  • 所谓的周边功能,比如性能统计,日志,事务管理等等

周边功能在 Spring 的面向切面编程AOP思想里,即被定义为切面

在面向切面编程AOP的思想里面,核心业务功能和切面功能分别独立进行开发,然后把切面功能和核心业务功能 “编织” 在一起,这就叫AOP

AOP 的目的

AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码降低模块间的耦合度,并有利于未来的可拓展性和可维护性

AOP 当中的概念:

  • 切入点(Pointcut)
    在哪些类,哪些方法上切入(where
  • 通知(Advice)
    在方法执行的什么实际(**when:**方法前/方法后/方法前后)做什么(**what:**增强的功能)
  • 切面(Aspect)
    切面 = 切入点 + 通知,通俗点就是:在什么时机,什么地方,做什么增强!
  • 织入(Weaving)
    把切面加入到对象,并创建出代理对象的过程。(由 Spring 来完成)

AOP 编程

  1. 在 Packge【service】下创建 【ProductService】类:
package service;public class ProductService {public void doSomeService(){System.out.println("doSomeService");}
}
  1. 在 xml 文件中装配该 bean:
<bean name="productService" class="service.ProductService" />
  1. 在【TestSpring】中编写测试代码,运行

  2. 在 Packge【aspect】下准备日志切面 【LoggerAspect】类:

package aspect;import org.aspectj.lang.ProceedingJoinPoint;public class LoggerAspect {public Object log(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("start log:" + joinPoint.getSignature().getName());Object object = joinPoint.proceed();System.out.println("end log:" + joinPoint.getSignature().getName());return object;}
}
  1. 在 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:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.0.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsd"><bean name="productService" class="service.ProductService" /><bean id="loggerAspect" class="aspect.LoggerAspect"/><!-- 配置AOP --><aop:config><!-- where:在哪些地方(包..方法)做增加 --><aop:pointcut id="loggerCutpoint"expression="execution(* service.ProductService.*(..)) "/><!-- what:做什么增强 --><aop:aspect id="logAspect" ref="loggerAspect"><!-- when:在什么时机(方法前//前后) --><aop:around pointcut-ref="loggerCutpoint" method="log"/></aop:aspect></aop:config>
</beans>
  1. 再次运行 TestSpring 中的测试代码,代码并没有改变,但是在业务方法运行之前和运行之后,都分别输出了日志信息:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/557007.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机与体育教育的关系,体育教学论文:健康教育与体育教育存在的问题研究...

摘要&#xff1a;确立“健康第一”的指导思想,使体育与健康教育相结合,使教育过程与教育目标、手段相统一,是当今世界经济发达国家学校体育工作的共同特点,也是学校体育学科发展的必然。该文通过《体育与健康》课改过程中尚存问题的研究,提出相应的对策,以实现体育教育向素质教…

Spring中@Autowired和@Resource的区别

一、定义 Autowired 对类成员变量、方法及构造函数进行标注&#xff0c;完成自动装配的工作。 Resource 在语义上被定义为通过其唯一的名称来标识特定的目标组件&#xff0c;其中声明的类型与匹配过程无关。 如果没有明确指定名称&#xff0c;则默认名称是从字段名称或设置…

全国计算机考试真考题库4,全国计算机等级考试无纸化真考题库试卷二级C--(4)资料.docx...

精品文档精品文档PAGEPAGE #欢迎下载全国计算机等级考试无纸化真考题库试卷(4)二级 C(考试时间120分钟&#xff0c;满分100分)一、选择题(每小题1分&#xff0c;共40分)(1)下列数据结构中&#xff0c;属于非线性结构的是()。A)循环队列B)带链队列C)二叉树D)带链栈⑵下列数据结构…

Java面试题大全

一、Java 基础 1. JDK 和 JRE 有什么区别&#xff1f; JDK&#xff1a;Java Development Kit 的简称&#xff0c;java 开发工具包&#xff0c;提供了 java 的开发环境和运行环境。JRE&#xff1a;Java Runtime Environment 的简称&#xff0c;java 运行环境&#xff0c;为 ja…

每个计算机系的学生都学离散数学,离散数学一阶逻辑精要.ppt

离散数学一阶逻辑精要.ppt2.谓词公式 中量词 的辖域是( ). A. B. C. D. 3.谓词公式 中变元 是( ). A. 自由变元 B. 约束变元 C. 既不是自由变元也不是约束变元 D. 既是自由变元也是约束变元 4.若个体域为整数域&#xff0c;下列公式中真值为1的是 ( ). A. B. C. D. 5. 设A(x):x…

压力测试软件je,Jemeter压力测试工具

![JMeter](https://img.tnblog.net/arcimg/hb/fcfd7c903b184e5e9db56360fed8c7a7.png "JMeter")>#Jemeter 压力测试工具[TOC]JMeter 简介------------>阿帕奇JMeter的?应用程序是开源软件&#xff0c;100&#xff05;纯Java应用而设计的负载测试功能行为和测量…

Java面试题整理(附参考答案)

1、面向对象的特征有哪些方面&#xff1f; 抽象&#xff1a;将同类对象的共同特征提取出来构造类。继承&#xff1a;基于基类创建新类。封装&#xff1a;将数据隐藏起来&#xff0c;对数据的访问只能通过特定接口。多态性&#xff1a;不同子类型对象对相同消息作出不同响应。 …

沈阳药科大学计算机二级好考吗,沈阳药科大学考研难吗?一般要什么水平才可以进入?...

沈阳药科大学考考研难吗&#xff1f;其实并不能一概而论。要看我们每个学生的实际情况。例如&#xff1a;本科院校是哪个层级的&#xff0c;专业考取是否为跨专业&#xff1f;专业是否是热门学科&#xff1f;学校分数线是多少&#xff1f;历年录取人数是多少&#xff1f;接下来…

SpringMVC源码之参数解析绑定原理

SpringMVC源码之参数解析绑定原理 摘要 本文从源码层面简单讲解SpringMVC的参数绑定原理 SpringMVC参数绑定相关组件的初始化过程 在理解初始化之前&#xff0c;先来认识一个接口 HandlerMethodArgumentResolver 方法参数解析器接口&#xff0c;这个接口是SpringMVC参数解…

win7 找不到 计算机策略组,win7打开组策略报错:找不到资源string.Advanced_EnableSSL3Fallback...

今天要在组策略里关闭几个端口&#xff0c;每次打开组策略时都弹出一个错误提示框&#xff0c;说是找不到资源“string.Advanced_EnableSSL3Fallback”。找不到资源string.Advanced_EnableSSL3Fallback我的系统好好的&#xff0c;怎么会这样呢&#xff1f;一时间不知如何解决。…

@RequestParam 注解原理

RequestParam 注解原理 注&#xff1a;SpringMVC 版本 5.2.15 介绍 RequestParam 注解用于绑定请求参数。它的具体内容如下&#xff1a; // 该注解作用的方法形参 Target(ElementType.PARAMETER) Retention(RetentionPolicy.RUNTIME) Documented public interface RequestPar…

xbox虚拟服务器,Xbox One平台真相:原生Win8/虚拟化运行

Xbox One搭载的是Windows8吗&#xff1f;没错。在Build2014开发者大会上&#xff0c;Frank Savage介绍Xbox One平台未来的开发计划&#xff0c;其中他也揭秘Xbox One平台运行原生Win8系统&#xff0c;那些主机游戏均采用虚拟化技术加载运行。据国外wccftech科技网站透露&#x…

SpringMVC 执行流程解析

SpringMVC 执行流程解析 注&#xff1a;SpringMVC 版本 5.2.15 上面这张图许多人都看过&#xff0c;本文试图从源码的角度带大家分析一下该过程。 1. ContextLoaderListener 首先我们从 ContextLoaderListener 讲起&#xff0c;它继承自 ServletContextListener&#xff0c;用…

无线网服务器mac是什么,电脑MAC和LAN MAC以及WIRELESS MAC是什么关系?

满意答案刘义芳aaa推荐于 2017.12.14采纳率&#xff1a;51% 等级&#xff1a;12已帮助&#xff1a;19753人一楼和二楼的回答都是对的电脑MAC这样说不好理解的&#xff0c;应该说MAC电脑&#xff0c;MAC是Macintosh这个的前三个字母&#xff0c;至于它为什么只用前三个字母做…

mybatis 中 foreach collection的三种用法

foreach的主要用在构建in条件中&#xff0c;它可以在SQL语句中进行迭代一个集合。 foreach元素的属性主要有 item&#xff0c;index&#xff0c;collection&#xff0c;open&#xff0c;separator&#xff0c;close。 item表示集合中每一个元素进行迭代时的别名&#xff0c;i…

@RequestParam详解

RequestParam 主要用于将请求参数区域的数据映射到控制层方法的参数上 首先我们需要知道RequestParam注解主要有哪些参数 value&#xff1a;请求中传入参数的名称&#xff0c;如果不设置后台接口的value值&#xff0c;则会默认为该变量名。比如上图中第一个参数如果不设置va…

Java new关键字和newInstance()方法的区别

1、类的加载方式不同 在执行Class.forName(“a.class.Name”)时&#xff0c;JVM会在classapth中去找对应的类并加载&#xff0c;这时JVM会执行该类的静态代码段。在使用newInstance()方法的时候&#xff0c;必须保证这个类已经加载并且已经连接了&#xff0c;而这可以通过Clas…

springboot 的 RedisTemplate 的 execute 和 executePipelined 功能的区别redis

1.executespring 如下是 springboot 官网原文:springboot Redis provides support for transactions through the multi, exec, and discard commands. These operations are available on RedisTemplate, however RedisTemplate is not guaranteed to execute all operatio…

Error running ‘Tomcat‘: Unable to open debugger port (127.0.0.1:2148): java.net.SocketExceptio

在Web项目运行的时候&#xff0c;IDEA可能会报Error running ‘Tomcat’: Unable to open debugger port (127.0.0.1:2148): java.net.SocketException “socket closed”错误&#xff0c;启动不了Tomcat&#xff0c;在这种时候&#xff0c;网上的解决办法大多都是修改端口的这…

# hive打不开,提示节点过少,进入安全模式~~

hive打不开,提示节点过少&#xff0c;进入安全模式~~ 前段时候给电及除尘&#xff0c;因为经常拆着玩&#xff0c;越熟练越容易大意&#xff0c;一下子把电源排线扯坏了。挼了挼&#xff0c;想凑和着用吧&#xff0c;没想到不知怎么的就会关机&#xff0c;太频繁了。一怒之下取…