Spring 概述

Spring框架是一个轻量级的企业级开发的一站式解决方案。所谓一站式解决方案,就是可以基于Spring解决JavaEE开发中的所有问题,他主要提供IoC容器、AOP、数据访问、Web开发、消息、测试等相关技术的支持。

Spring简史

  1. 在Spring1.x时代,采用xml配置。

  2. 在Spring2.x时代,由于JDK1.5开始支持注解,所以Spring提供了@Service、@Component等注解,大大减少了配置量。

  3. 在Spring3.x到现在,使用JavaConfig配置。Spring4.x和SpringBoot都推荐使用这种方式。

  4. 当前Spring最新发布的版本是5.x

Spring 框架模块简介

  1. Spring-Core:核心工具类,其他模块正常使用的基础。

  2. Spring-Beans:Spring定义的Bean的支持,提供 BeanFactory,它是一个工厂模式的复杂实现。

  3. Spring-Context:运行时Spring容器

  4. Spring-Context-Support:Spring容器对第三方包集成的支持, 比如邮件服务、视图解析等

  5. Spring-SpEL(Spring-Expression):使用表达式语言在运行时查询和操作对象

  6. spring-jdbc:jdbc的支持

  7. spring-tx:事务控制

  8. spring-orm:对象关系映射,集成orm框架

  9. spring-oxm:对象xml映射

  10. spring-jms:java消息服务

  11. Spring-AOP:基于代理的AOP支持。

  12. Spring-Aspects:基于AspectJ的AOP支持。

  13. Spring-instrument:提供一些类级的工具支持和ClassLoader级的实现,用于服务器

  14. Spring-web:基础web功能,在Web项目中提供Spring容器

  15. Spring-webmvc:基于Servlet的mvc实现

  16. Spring-webmvc-portlet:基于portlet的mvc实现

  17. Spring-Messaging:用于构建基于消息的应用程序,对消息架构和协议的支持。

  18. Spring-Websocket:主要用于即时通讯

  19. Spring-Test:spring测试,提供junit与mock测试功能,支持JUnit 或 TestNG框

Spring 核心

一、为什么使用 Spring

1、方便解耦,简化开发 通过Spring提供的 IoC 容器,可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。 2、AOP 编程的支持 通过Spring提供的 AOP 功能,方便进行面向切面的编程,如性能监测、事务管理、日志记录等。 3、声明式事务的支持 4、方便集成各种优秀框架 5、降低Java EE API的使用难度:如对 JDBC,JavaMail,远程调用等提供了简便封装

二、什么是 IoC,为什使用 IoC IoC 全称 Iversion of Controller,控制反转。 这概念是说你不用创建对象,而只需要描述它如何被创建。

三、什么是 AOP,为什么使用 AOP AOP 全称:Aspect-Oriented Programming,面向切面编程。 面向切面编程,就是把可重用的功能提取出来,然后将这些通用功能在合适的时候织入到应用程序 中,比如事务管理、权限控制、日志记录、性能统计等。

Spring 容器如何初始化

基于配置文件的方式

//默认查找classpath路径下的文件
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring/spring-ioc.xml");

//多文件,也可传递数组
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring/spring-ioc.xml","spring/spring-ioc2.xml");

//默认为项目工作路径 即项目的根目录
ApplicationContext applicationContext= new FileSystemXmlApplicationContext("/src/main/resources/spring/spring-ioc.xml");

//也可以读取classpath下的文件
ApplicationContext applicationContext=new FileSystemXmlApplicationContext("classpath:spring/spring-ioc.xml");

//使用前缀file 表示的是文件的绝对路径
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("file:D:/app.spring.xml");


基于@Configuration注解的方式
AnnotationConfigApplicationContext config=new AnnotationConfigApplicationContext(BeanConfiguration.class);
//名称必须BeanConfiguration中工程方法名称一致
IUserService userService= (IUserService) config.getBean(“userService");
userService.doSomething();

Spring Bean的初始化过程

Spring IOC 组件按其所承担的角色可以划分为两类:

  1. 物料组件

    1. Resource:配置文件配置的资源

    2. BeanDefinition:通过资源解析产生的Bean定义对象

    3. PropertyEditor:记录各Bean的属性依赖

    4. 以及最终的Bean,它们是加工流程中被加工、被消费的组件,就像流水线上被加工的物料。

  2. 加工设备组件

    1. ResourceLoader:资源加载器

    2. BeanDefinitionReader:Bean解析器

    3. BeanFactoryPostProcessor:Bean信息加工机器

    4. InstantiationStrategy:实例化对象机器

    5. BeanWrapper:Bean属性设置器,这些加工组件像是流水线上不同环节的加工设备,对物料组件进行加工处理。

流程图:

自定义 Spring IOC 容器--基于注解的 IOC 容器

新建Bean工厂UdaBeanFactory.java 定义beanMap用于存储Bean名称、类型与对象映射 新建容器对象UdaSpringContext.java 定义udaBeanFactory,用于创建bean及相关依赖,获取Bean 配置扫描路径,初始化容器时,扫描路径下所有有注解的class,实例化Bean存储到bean工厂中 定义注解 @UdaComponent:作用在类上,表示一个Bean,让自定义容器管理 @UdaAutowired:作用在字段上,用于注入

为什么要用 AOP

改进的方式:

  1. 抽取通用方法

  2. 提取父类

改进的方式虽然能大大减少代码的冗余,但时随着软件开发的系统越来越复杂,核心业务中总掺杂着一些不相关联的外围业务,如日志记录,权限验证,事务控制,性能检测,错误信息检测等等。

这些外围业务可以说和核心业务没有根本上的关联而且核心业务也不关心它们 而且这些外围操作同样会在其他业务模块中出现,这样就会造成如下问题

1、代码混乱:核心业务模块可能需要兼顾处理其他不相干的业务外围操作。 2、代码分散和冗余:同样的功能代码,在其他的模块几乎随处可见,导致代码分散并且冗余度高。

3、代码质量低扩展难:由于不太相关的业务代码混杂在一起,无法专注核心业务代码,拓展性低。

AOP简介

AspectJ-AOP:AspectJ是AOP的领跑者,它采用的静态织入的方式。ApectJ主要采用的是编译期织入,在这个期间使用AspectJ的acj编译器(类似javac )把aspect类编译成class字节码后,在java目标类编译时织入,即先编译aspect类再编译目标类。

Spring-AOP: Spring AOP的实现原理是基于动态代理织入的方式。动态代理技术又分为Java JDK动态代理和CGLIB动态代理,前者是基于反射技术的实现,后者是基于继承的机制实现。

AOP 实现原理

基于JDK的动态代理

1、创建代理类JDKProxy,实现InvocationHandler接口 2、定义业务类,业务类必须实现接口,通过业务类创建代理对象 3、JDKProxy中定义创建代理对象的方法Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);

基于CGLIB的动态代理 通过CGLIB动态代理实现上述功能并不要求目标对象拥有接口类,实际上CGLIB动态代理是通过继承的方式实现的,因此可以减少没必要的接口。 1、创建代理对象CGLibProxy,实现MethodInterceptor接口 2、定义业务类,业务类不需要有接口,通过业务类创建代理对象 3、CGLibProxy提供创建代理对象的方法

posted on 2021-01-06 17:02  白糖℃  阅读(522)  评论(0编辑  收藏  举报