Skip to content

Spring基础 #23

Description

@cyjxiaozhi

一、什么是Spring?
首先Spring的出现是为了将Java开发更为容易一些,同时,Spring之所以与Struts、Hibernate等单层框架不同,是因为Spring致力于提供一个以统一的、高效的方式构造整个应用,并且可以将单层框架以最佳的组合揉和在一起建立一个连贯的体系。可以说Spring是一个提供了更完善开发环境的一个框架,可以为POJO(Plain Ordinary Java Object)对象提供企业级的服务。

二、Spring框架的特性
非侵入式:基于Spring开发的应用中的对象可以不依赖于Spring的API

控制反转:IOC——Inversion of Control,指的是将对象的创建权交给 Spring 去创建。使用 Spring 之前,对象的创建都是由我们自己在代码中new创建。而使用 Spring 之后。对象的创建都是给了 Spring 框架。

依赖注入:DI——Dependency Injection,是指依赖的对象不需要手动调用 setXX 方法去设置,而是通过配置赋值。
面向切面编程:Aspect Oriented Programming——AOP

容器:Spring 是一个容器,因为它包含并且管理应用对象的生命周期组件化:Spring 实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象。

一站式:在 IOC 和 AOP 的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上 Spring 自身也提供了表现层的 SpringMVC 和持久层的 Spring JDBC)

三、SpringFramework有哪些组件?
image
具体的每个组件的源码和细节,后面再具体展开

四、简单例子
image

目前项目的里的结构如此,如果没有SpringFramework我们可能在这里就需要自己去进行创建

1.对于控制反转
如果没有Spring框架,我们需要自己创建User/Dao/Service等,比如:UserDaoImpl userDao = new UserDaoImpl();
UserSericeImpl userService = new UserServiceImpl();
userService.setUserDao(userDao);
List userList = userService.findUserList();

这些Bean现在是由框架来给我们创建,则我们能够理解什么叫做控制反转,Spring框架管理这些Bean的创建工作,即由用户管理Bean转变为框架管理Bean,这个就叫控制反转 - Inversion of Control (IoC)

Spring 框架托管创建的Bean放在哪里呢? 这便是IoC Container;

那怎么去配置Bean呢,这里就延伸出注解配置、xml配置、Java配置

再进一步,框架接管了Bean,那就会负责Bean的生命周期

应用程序中从IoC容器内获得依赖的Bean,注入到程序中,这就叫依赖注入,所以说控制反转是通过依赖注入实现的,其实它们是同一个概念的不同角度描述。通俗来说就是IoC是设计思想,DI是实现方式

在依赖注入时,有哪些方式呢?这就是构造器方式,@Autowired, @resource, @qualifier... 同时Bean之间存在依赖(可能存在先后顺序问题,以及循环依赖问题等)

2.对于AOP
下面我们给出例子来看两种实现AOP的方式
(1)基于XML来实现AOP添加日志给所有service
首先添加依赖
image

定义Service层接口和实现类
image

创建切面类用于记录日志
创建一个切面类,在其中定义通知(Advice)方法,用于在目标方法(Service 层方法)执行前后等时机添加日志记录逻辑。示例如下:
image

在上述切面类中:
@before 注解标注的方法是前置通知,在目标 Service 层方法执行前获取方法名称并记录一条日志信息,表示即将执行该方法。
@AfterReturning 注解标注的方法是后置通知,当目标方法正常执行完毕后,记录方法执行成功的日志。
@AfterThrowing 注解标注的方法是异常通知,若目标方法执行过程中抛出异常,会记录方法执行出现异常以及异常的具体信息的日志。
@around 注解标注的方法是环绕通知,它可以完全控制目标方法的执行过程,这里在方法执行前后分别记录进入和退出的日志,并通过 proceedingJoinPoint.proceed() 来触发目标方法的实际执行,最后返回目标方法的执行结果。

配置Spring XML 文件(添加 AOP 配置)
在 Spring 的配置文件(如applicationContext.xml)中添加 AOP 相关的配置内容,使得切面能够生效并织入到目标 Service 层方法中,示例配置如下:
image

这里通过 <aop:aspectj-autoproxy /> 开启了 AOP 自动代理功能,使得 Spring 能够自动识别切面类(带有 @aspect 注解的类)并将切面织入到符合条件的目标方法(通过 execution(* com.example.service..(..)) 定义的 Service 层方法)中,context:component-scan 用于扫描项目中的组件(如 @service 标注的 Service 类以及 @aspect 标注的切面类等)。

(2)基于注解实现
前面都是一样,在最后一步不同的是创建一个带有 @configuration 注解的配置类,在其中通过 @EnableAspectJAutoProxy 注解开启 AOP 自动代理功能,示例配置类如下:
image
通过 @EnableAspectJAutoProxy 注解告诉 Spring 框架启用 AspectJ 的自动代理机制,这样 Spring 就会自动扫描并将切面(带有 @aspect 注解的 LoggingAspect 类)织入到符合条件(通过 execution(* com.example.service..(..)) 定义的 Service 层方法)的目标方法中,从而实现给 Service 层所有方法调用添加日志的功能。

则进一步可以延伸出其他知识:
Spring 框架通过定义切面, 通过拦截切点实现了不同业务模块的解耦,这个就叫面向切面编程 - Aspect Oriented Programming (AOP)

为什么@aspect注解使用的是aspectj的jar包呢?这就引出了Aspect4J和Spring AOP的历史渊源,只有理解了Aspect4J和Spring的渊源才能理解有些注解上的兼容设计

如何支持更多拦截方式来实现解耦, 以满足更多场景需求呢? 这就是@around, @pointcut... 等的设计

那么Spring框架又是如何实现AOP的呢? 这就引入代理技术,分静态代理和动态代理,动态代理又包含JDK代理和CGLIB代理等

3.SpringFramework是怎么简化代码开发的呢?
image
Springboot实际上通过约定大于配置的方式,使用xx-starter统一的对Bean进行默认初始化,用户只需要很少的配置就可以进行开发了。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions