目录
[1.1 Spring简介](#t1)
[1.2 优点](#t2)
[1.3 组成](#t3)
[1.4 拓展](#t4)
[2.1 IoC简介](#t6)
[2.2 IoC本质](#t7)
[2.3 HelloSpring](#t8)
[2.3.1 导入Jar包](#t9)
[2.3.2 编写代码](#t10)
[2.3.3 思考](#t11)
[3.1 什么是AOP?](#t13)
[3.2 Aop基本概念](#t14)
[3.3 使用Spring实现Aop](#t15)
[3.3.1 使用AOP织入,需要导入一个依赖包](#t16)
[3.3.2 编写学生类](#t17)
[3.3.3 编写AOP类](#t18)
[3.3.4 编写applicationContext.xml](#t19)
[3.3.5 编写测试类](#t20)
[3.3.6 测试结果](#t21)
1、Spring概述
1.1 Spring简介
- Spring : 春天 —>给软件行业带来了春天
- 2002年,Rod Jahnson首次推出了Spring框架雏形interface21框架。
- 2004年3月24日,Spring框架以interface21框架为基础,经过重新设计,发布了1.0正式版。
- 很难想象Rod Johnson的学历 , 他是悉尼大学的博士,然而他的专业不是计算机,而是音乐学。
- Spring理念 : 使现有技术更加实用 . 本身就是一个大杂烩 , 整合现有的框架技术
官网 : Spring | Home
官方下载地址 : JFrog (spring.io)
GitHub : Spring · GitHub
1.2 优点
- Spring是一个开源免费的框架 , 容器 .
- Spring是一个轻量级的框架 , 非侵入式的 .
- 控制反转 IoC , 面向切面 Aop
- 对事物的支持 , 对框架的支持
- Spring通过DI、AOP和消除样板式代码来简化企业级Java开发
- Spring框架之外还存在一个构建在核心框架之上的庞大生态圈,它将Spring扩展到不同的领域,如Web服务、REST、移动开发以及NoSQL
- 独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere的承诺
- Spring的IoC容器降低了业务对象替换的复杂性,提高了组件之间的解耦
- Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式处理,从而提供了更好的复用
- Spring的ORM和DAO提供了与第三方持久层框架的的良好整合,并简化了底层的数据库访问
- Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部。
一句话概括:Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架)。
1.3 组成
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。
1.4 拓展
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。
2、IoC和依赖注入
2.1 IoC简介
IoC的全称为Inversion of Control,即控制反转,意为把对资源的控制权反转过来。IoC不是一项开发技术,也不是具体功能,而是面向对象编程中的一种设计理念。
2.2 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)。
2.3 HelloSpring
2.3.1 导入Jar包
注 : spring 需要导入commons-logging进行日志记录 . 我们利用maven , 他会自动下载对应的依赖项 .
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.10.RELEASE</version></dependency>
2.3.2 编写代码
1. 编写一个Hello实体类
public class Hello { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public void show(){ System.out.println("Hello,"+ name ); }}
2.编写我们的spring文件 , 这里我们命名为beans.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"> <!--bean就是java对象 , 由Spring创建和管理--> <bean id="hello" class="com.kuang.pojo.Hello"> <property name="name" value="Spring"/> </bean></beans>
3. 我们可以去进行测试了 .
@Testpublic void test(){ //解析beans.xml文件 , 生成管理相应的Bean对象 ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); //getBean : 参数即为spring配置文件中bean的id . Hello hello = (Hello) context.getBean("hello"); hello.show();}
2.3.3 思考
- Hello 对象是谁创建的 ? 【 hello 对象是由Spring创建的 】
- Hello 对象的属性是怎么设置的 ? 【hello 对象的属性是由Spring容器设置的 】
这个过程就叫控制反转 :
- 控制 : 谁来控制对象的创建 , 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , 对象是由Spring来创建的
- 反转 : 程序本身不创建对象 , 而变成被动的接收对象 .
依赖注入 : 就是利用set方法来进行注入的.
- IOC是一种编程思想,由主动的编程变成被动的接收
- 所谓的IoC,一句话搞定 : 对象由Spring 来创建 , 管理 , 装配 !
3、AOP
3.1 什么是AOP?
AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
3.2 Aop基本概念
AOP是依赖动态代理实现的,具体步骤:先把业务代码中的共性内容抽离出来,然后通过动态代理的方式把抽离出来的共性代码织入业务代码中来实现对原有代码的增强处理。
在原有代码乃至原业务流程都不修改的情况下,直接在业务流程中切入新代码,增加新功能,这就是AOP。
- Aspect(切面):一个模块化的横向逻辑(或称横切关注点),可能会横切多个对象。
- Advice(增强处理):切面在某个特定连接点上执行的代码逻辑。
- Join Point(连接点):程序执行中的某个具体的执行点。
- Pointcut(切入点):对连接点的特征进行描述,可以使用正则表达式。增强处理和一个切入点表达式相关联,并在与这个切入点匹配的某个连接点上运行。
- Target Object(目标对象):被一个或多个切面增强的对象。
- AOP proxy(AOP代理):由AOP框架所创建的对象,实现执行增强处理方法等功能。
- Weaving(织入):将增强处理连接到应用程序中的类型或对象上的过程。
- 增强处理类型:前置增强丶后置增强丶环绕增强丶异常抛出增强丶最终增强等类型。
3.3 使用Spring实现Aop
3.3.1 使用AOP织入,需要导入一个依赖包
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --><dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version></dependency>
3.3.2 编写学生类
package entity; import org.aspectj.lang.JoinPoint; public class Student { public int study(int i){ System.out.println("学生在学习!"); /*throw new NullPointerException();*/ return 3; }}
3.3.3 编写AOP类
package aop; import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint; /** 后续你要新植入的方法* */public class MyAop { /*前置增强*/ public void washFace(JoinPoint jp){ System.out.println("输出了参数:"+jp); System.out.println("学生先洗脸"); } /*后置增强带返回值*/ public void eat(JoinPoint jp,Object result){ System.out.println("获取到返回值:"+result); System.out.println("学习之后要吃饭"); } /*最终增强*/ public void Myfinal(JoinPoint jp){ System.out.println("我是最终增强!"); } /*环绕增强:1.前置 2.后置*/ /*目标方法有返回值那么环绕增强也得有返回值*/ public Object around(ProceedingJoinPoint pjd){ Object result=null; System.out.println("环绕的前方"); try { result = pjd.proceed();//让目标方法执行 System.out.println("目标方法返回值:"+result); } catch (Throwable e) { e.printStackTrace(); } System.out.println("环绕的后方"); return result; } /*异常增强*/ public Object error(JoinPoint jp,Exception e){ System.out.println("我是异常增强,报错就有我!"); return 123; }}
3.3.4 编写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" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" xmlns:aop="http://www.springframework.org/schema/aop" 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 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="stu" class="entity.Student"> </bean> <bean id="aop" class="aop.MyAop"> </bean> <!--面向切面--> <aop:config> <!--找到切点--> <aop:pointcut id="pc" expression="execution(public int study(..))"/> <!--通过切点,打开切面 ,引入新需求--> <aop:aspect ref="aop"> <!--异常增强--> <aop:after-throwing method="error" pointcut-ref="pc" throwing="e"/> <!--异常增强和环绕增强不能同时使用--> <!--最终增强--> <aop:after method="Myfinal" pointcut-ref="pc"/><!--顺序会影响输出的结果--> <!--before前置增强--> <aop:before method="washFace" pointcut-ref="pc"/> <!--环绕增强--> <aop:around method="around" pointcut-ref="pc"/> <!--after-returning后置增强可以获取目标的返回值--> <aop:after-returning method="eat" pointcut-ref="pc" returning="result"/> </aop:aspect> </aop:config></beans>
3.3.5 编写测试类
package test; import entity.*;import org.aspectj.lang.JoinPoint;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.List;import java.util.Map; public class test { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //通过工厂的指定流水线 来生产 //控制反转:让创建对象的过程交给ioc容器来做,统一管理 //依赖注入(set注入):Bean对象所依赖的资源 , 由容器来设置和装配 Student st=context.getBean("stu",Student.class); st.study(2); }}
3.3.6 测试结果
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).log4j:WARN Please initialize the log4j system properly.log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.输出了参数:execution(int entity.Student.study(int))学生先洗脸环绕的前方学生在学习!我是最终增强!目标方法返回值:3环绕的后方获取到返回值:3学习之后要吃饭 进程已结束,退出代码为 0
4、本章总结
- Spring是一个轻量级的企业框架,提供了IoC丶AOP丶ORM集成丶Web集成等功能。
- Spring是一个超级黏合平台,对已有优秀框架支持良好。
- Spring通过配置文件完成Bean的组装工作,避免Bean之间产生直接依赖。
- IoC是一种程序设计思想,依赖注入是这种思想的一种具体实现方式。
- AOP主要关心两个问题:在什么位置,执行什么功能。
- AOP的目的是从系统中分离出切面,独立于业务逻辑实现,在程序执行时织入程序中运行。
- 配置AOP主要使用aop命名空间下的元素完成,可以实现定义切入点和织入增强等操作。