前言
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
IOC
1.IOC的概念
控制反转(IoC=Inversion of Control)IoC,用白话来讲,就是由容器控制程序之间的(依赖)关系,而非传统实现中,由程序代码直接操控。这也就是所谓“控制反转”的概念所在:(依赖)控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。
IoC还有一个另外的名字:“依赖注入 (DI=Dependency Injection)” ,即由容器动态的将某种依赖关系注入到组件之中
案例:实现Spring的IoC
IOC/DI
将以前由程序员实例化对象/赋值的工作交给了spring处理
2.IOC的运用
Spring IoC容器常用的实现是ApplicationContext,它是一个具有丰富功能的IoC容器。通过在配置文件中定义Bean的信息,或使用注解方式进行配置,应用程序可以借助ApplicationContext来获取所需的Bean实例,并利用容器提供的功能,如AOP(面向切面编程)、事务管理等。
3.IOC的特点
Spring IoC通过将对象的创建、组装和管理任务交给容器来完成,实现了对象之间的解耦和灵活性。它简化了应用程序的开发和维护,提高了代码的可复用性和可测试性。同时,Spring IoC还提供了丰富的功能和扩展点,使得开发者可以更加方便地进行企业级应用程序的开发。
4.IOC的底层逻辑
IoC 底层通过工厂模式、Java 的反射机制、XML 解析等技术,将代码的耦合度降低到最低限度,其主要步骤如下。
- 在配置文件(例如 Bean.xml)中,对各个对象以及它们之间的依赖关系进行配置;
- 我们可以把 IoC 容器当做一个工厂,这个工厂的产品就是 Spring Bean;
- 容器启动时会加载并解析这些配置文件,得到对象的基本信息以及它们之间的依赖关系;
- IoC 利用 Java 的反射机制,根据类名生成相应的对象(即 Spring Bean),并根据依赖关系将这个对象注入到依赖它的对象中。
5.IOC的注入方式
a.set注入 property name value ref
基本数据注入
String
自定义类型注入(开放中常用)
b.构造注入 construct-arg
c.自动装配
byName 根据当前Bean对象中属性名去spring上下文
byType 根据接口自动在spring的上下文去找实现类
AOP
1.AOP的概念
Spring AOP(Aspect-oriented Programming,面向切面编程)是Spring框架提供的一个重要特性,用于实现横切关注点的模块化和可重用性。它通过在不修改原有业务逻辑代码的情况下,将横切关注点与核心业务逻辑进行解耦,并通过切面(Aspect)来定义和管理这些关注点。
在传统的面向对象编程中,业务逻辑代码通常分散在各个对象中,而横切关注点(如日志记录、事务管理、安全控制等)则相互交织其中,导致代码的重复和难以维护。而Spring AOP则将横切关注点作为一个独立的模块,称为切面(Aspect),并通过一种称为切入点(Pointcut)的机制来选择在哪些连接点(Joinpoint)上应用切面。
AOP—— 即面向切面编程
2.AOP的核心
Spring AOP的核心概念包括以下几个:
目标(Target):被通知(被代理)的对象
连接点(Joinpoint):连接点是程序执行过程中可以插入切面的点。例如方法的调用、方法的执行、字段的访问等。
通知(Advice):通知定义了切面在连接点上执行的行为。包括前置通知(Before)、后置通知(After)、返回通知(After-returning)、异常通知(After-throwing)和环绕通知(Around)。
代理(Proxy):将通知应用到目标对象后创建的对象(代理=目标+通知),
切入点(Pointcut):切入点是通过表达式或注解来选择在哪些连接点上应用切面。连接点可以是方法的执行、方法的调用、字段的访问等。
适配器(Advisor):适配器=通知(Advice)+切入点(Pointcut)
切面(Aspect):切面是横切关注点的模块化和可重用单元。它由切入点、通知和其他配置元素组成。切面定义了应该在哪些连接点上执行特定的行为。
Spring AOP可以与Spring IoC容器无缝集成,通过配置文件或注解方式将切面定义为Bean,并由容器负责管理和应用。Spring AOP的实现基于动态代理技术,可以使用JDK动态代理或CGLIB字节码生成库来创建代理对象。
3.AOP的代理
工具类org.springframework.aop.framework.ProxyFactoryBean用于创建代理对象,并且在一般情况下需要注入以下三个属性:
-
proxyInterfaces:代理应该实现的接口列表(List)。这个属性指定了代理对象应该实现的接口列表,通过实现这些接口,代理对象可以对外提供与目标对象相同的接口方法。
-
interceptorNames:需要应用到目标对象上的通知Bean的名字(List)。这个属性指定了应该应用到目标对象上的通知Bean的名字列表。通知Bean是实现切面逻辑的对象,它定义了在目标对象的特定连接点上执行的操作。
-
target:目标对象(Object)。这个属性指定了被代理的目标对象,即需要被代理的实际业务对象。
通过设置以上三个属性,ProxyFactoryBean可以根据配置创建一个代理对象,该代理对象可以拥有与目标对象相同的接口,并在方法调用前后应用通知逻辑。
<bean id="targetObject" class="com.example.TargetObject" />
<bean id="adviceBean" class="com.example.AdviceBean" />
<bean id="proxyFactory" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>com.example.TargetInterface</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>adviceBean</value>
</list>
</property>
<property name="target" ref="targetObject" />
</bean>
ProxyFactoryBean创建了一个代理对象,该代理对象实现了com.example.TargetInterface接口,并应用了名为adviceBean的通知Bean。被代理的目标对象是targetObject。
通过配置ProxyFactoryBean,我们可以将切面逻辑(adviceBean)与目标对象(targetObject)进行解耦,并最终得到一个代理对象,该代理对象可以在目标对象的方法调用前后执行通知逻辑。
ProxyFactoryBean提供了一种简单而灵活的方式来实现AOP和动态代理,可以帮助我们在应用程序中实现横切关注点的分离,并增加代码的可维护性和重用性。
4.AOP的通知类型
前置通知:在连接点之前执行的通知()
实现org.springframework.aop.MethodBeforeAdvice接口
买书、评论前加系统日志
后置通知:在连接点正常完成后执行的通知
实现org.springframework.aop.AfterReturningAdvice接口
买书返利(存在bug)
环绕通知:包围一个连接点的通知,最大特点是可以修改返回值,由于它在方法前后都加入了自己的逻辑代码,因此功能异常强大。
org.aopalliance.intercept.MethodInterceptor
类似拦截器,会包括切入点,目标类前后都会执行代码。
异常通知:这个通知会在方法抛出异常退出时执行
org.springframework.aop.ThrowsAdvice
出现异常执行系统提示,然后进行处理。价格异常为例
过滤通知(适配器):适配器=通知(Advice)+切入点(Pointcut)
org.springframework.aop.support.RegexpMethodPointcutAdvisor
处理买书返利的bug