手写Spring高级源码(六): Spring AOP 应⽤

spring中的前置处理器和后置处理器区别 背景: SpringIOC容器它会以某种方式,加载配置文件中的 信息,将其解析为一个个的BeanDefinition.之后将BeanDefinition注册到容器之中。Spring IOC容器在实现的时候经过的过程可以使用如下图片表示: 分为两个主要部分: 其一 :容器启动阶段 其二:bean实例化阶段。 在容器的启动阶段主要做的是一些信息收集的过程(主要依赖于工具类BeanDefinitionReader),将收集的信息组成BeanDefinition.将BeanDefinition注册到相应的 阅读详情

第六部分 Spring AOP 应⽤

 
AOP 本质:在不改变原有业务逻辑的情况下增强横切逻辑,横切逻辑代码往往是权限校验代码、⽇志代码、事务控制代码、性能监控代码。

 

第1节 AOP 相关术语

1.1 业务主线

 
在讲解AOP术语之前,我们先来看⼀下下⾯这两张图,它们就是第三部分案例需求的扩展(针对这些扩展的需求,我们只进⾏分析,在此基础上去进⼀步回顾AOP ,不进⾏实现)

 

上图描述的就是未采⽤ AOP 思想设计的程序,当我们红⾊框中圈定的⽅法时,会带来⼤量的重复劳动。程序中充斥着⼤量的重复代码,使我们程序的独⽴性很差。⽽下图中是采⽤了AOP 思想设计的程序,它把红框部分的代码抽取出来的同时,运⽤动态代理技术,在运⾏期对需要使⽤的业务逻辑⽅法进⾏增强。

 

1.2 AOP 术语

连接点:⽅法开始时、结束时、正常运⾏完毕时、⽅法异常时等这些特殊的时机点,我们称之为连接点,项⽬中每个⽅法都有连接点,连接点是⼀种候选点
切⼊点:指定 AOP 思想想要影响的具体⽅法是哪些,描述感兴趣的⽅法
Advice 增强:
第⼀个层次:指的是横切逻辑
第⼆个层次:⽅位点(在某⼀些连接点上加⼊横切逻辑,那么这些连接点就叫做⽅位点,描述的是具体的特殊时机)
Aspect 切⾯:切⾯概念是对上述概念的⼀个综合
Aspect 切⾯ = 切⼊点 + 增强 = 切⼊点(锁定⽅法) + ⽅位点(锁定⽅法中的特殊时机) + 横切逻辑
众多的概念,⽬的就是为了锁定要在哪个地⽅插⼊什么横切逻辑代码

第2节 Spring中AOP的代理选择

Spring 实现 AOP 思想使⽤的是动态代理技术
默认情况下, Spring 会根据被代理对象是否实现接⼝来选择使⽤ JDK 还是 CGLIB 。当被代理对象没有实现任何接⼝时,Spring 会选择 CGLIB 。当被代理对象实现了接⼝, Spring 会选择 JDK 官⽅的代理技术,不过我们可以通过配置的⽅式,让Spring 强制使⽤ CGLIB 。

第3节 Spring中AOP的配置⽅式

在 Spring 的 AOP 配置中,也和 IoC 配置⼀样,⽀持 3 类配置⽅式。
  • 第⼀类:使⽤XML配置
  • 第⼆类:使⽤XML+注解组合配置
  • 第三类:使⽤纯注解配置

第4节 Spring中AOP实现

需求:横切逻辑代码是打印⽇志,希望把打印⽇志的逻辑织⼊到⽬标⽅法的特定位置 (service 层 transfer
⽅法 )

4.1 XML 模式

Spring 是模块化开发的框架,使⽤ aop 就引⼊ aop 的 jar
  • 坐标
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-aop</artifactId>
 <version>5.1.12.RELEASE</version>
</dependency> <dependency>
 <groupId>org.aspectj</groupId>
 <artifactId>aspectjweaver</artifactId>
 <version>1.9.4</version>
</dependency>
  • AOP 核⼼配置
<!--
 Spring基于XML的AOP配置前期准备:
 在spring的配置⽂件中加⼊aop的约束
 xmlns:aop="http://www.springframework.org/schema/aop"
 http://www.springframework.org/schema/aop 
https://www.springframework.org/schema/aop/spring-aop.xsd 
 
 Spring基于XML的AOP配置步骤:
 第⼀步:把通知Bean交给Spring管理
 第⼆步:使⽤aop:config开始aop的配置
 第三步:使⽤aop:aspect配置切⾯
 第四步:使⽤对应的标签配置通知的类型
 ⼊⻔案例采⽤前置通知,标签为aop:before
-->
<!--把通知bean交给spring来管理-->
<bean id="logUtil" class="com.lagou.utils.LogUtil"></bean>
<!--开始aop的配置-->
<aop:config>
<!--配置切⾯-->
 <aop:aspect id="logAdvice" ref="logUtil">
 <!--配置前置通知-->
 <aop:before method="printLog" pointcut="execution(public *
com.lagou.service.impl.TransferServiceImpl.updateAccountByCardNo(com.lagou
.pojo.Account))"></aop:before>
 </aop:aspect>
</aop:config>
  • 细节
  • 关于切⼊点表达式
上述配置实现了对 TransferServiceImpl 的 updateAccountByCardNo ⽅法进⾏增强,在其执⾏之前,输出了记录⽇志的语句。这⾥⾯,我们接触了⼀个⽐较陌⽣的名称:切⼊点表达式,它是做什么的呢?我们往下看。
 
  • 概念及作⽤
切⼊点表达式,也称之为 AspectJ 切⼊点表达式, 指的是遵循特定语法结构的字符串,其作⽤是⽤于对符合语法格式的连接点进⾏增强。它是 AspectJ 表达式的⼀部分。
  • 关于AspectJ
AspectJ 是⼀个基于 Java 语⾔的 AOP 框架, Spring 框架从 2.0 版本之后集成了 AspectJ 框架中切⼊点表达式的部分,开始⽀持AspectJ 切⼊点表达式。
  • 切⼊点表达式使⽤示例
全限定⽅法名 访问修饰符 返回值 包名.包名.包名.类名.⽅法名(参数列表)
 全匹配⽅式:
 public void
com.lagou.service.impl.TransferServiceImpl.updateAccountByCardNo(c
om.lagou.pojo.Account)
 访问修饰符可以省略
 void
com.lagou.service.impl.TransferServiceImpl.updateAccountByCardNo(c
om.lagou.pojo.Account)
 返回值可以使⽤*,表示任意返回值
 *
com.lagou.service.impl.TransferServiceImpl.updateAccountByCardNo(c
om.lagou.pojo.Account)
 包名可以使⽤.表示任意包,但是有⼏级包,必须写⼏个
 *
....TransferServiceImpl.updateAccountByCardNo(com.lagou.pojo.Accou
nt)
 包名可以使⽤..表示当前包及其⼦包
 *
..TransferServiceImpl.updateAccountByCardNo(com.lagou.pojo.Account
)
 类名和⽅法名,都可以使⽤.表示任意类,任意⽅法
 * ...(com.lagou.pojo.Account)
 参数列表,可以使⽤具体类型
 基本类型直接写类型名称 : int
 引⽤类型必须写全限定类名:java.lang.String
 参数列表可以使⽤*,表示任意参数类型,但是必须有参数
 * *..*.*(*)
 参数列表可以使⽤..,表示有⽆参数均可。有参数可以是任意类型
 * *..*.*(..)
 全通配⽅式:
 * *..*.*(..)
  • 改变代理⽅式的配置
在前⾯我们已经说了, Spring 在选择创建代理对象时,会根据被代理对象的实际情况来选择的。被代理对象实现了接⼝,则采⽤基于接⼝的动态代理。当被代理对象没有实现任何接⼝的时候,Spring 会⾃动切换到基于⼦类的动态代理⽅式。
但是我们都知道,⽆论被代理对象是否实现接⼝,只要不是 fifinal 修饰的类都可以采⽤ cglib 提供的⽅式创建代理对象。所以Spring 也考虑到了这个情况,提供了配置的⽅式实现强制使⽤
基于⼦类的动态代理(即 cglib 的⽅式),配置的⽅式有两种
  • 使⽤aop:confifig标签配置
<aop:config proxy-target-class="true">
  • 使⽤ aop:aspectj-autoproxy 标签配置
<!--此标签是基于XML和注解组合配置AOP时的必备标签,表示Spring开启注解配置AOP
的⽀持-->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectjautoproxy>
  • 五种通知类型
  • 前置通知
配置⽅式: aop:before 标签
 作⽤:
 ⽤于配置前置通知。
 出现位置:
 它只能出现在aop:aspect标签内部
 属性:
 method:⽤于指定前置通知的⽅法名称
 pointcut:⽤于指定切⼊点表达式
 pointcut-ref:⽤于指定切⼊点表达式的引⽤
-->
<aop:before method="printLog" pointcut-ref="pointcut1">
</aop:before>
执⾏时机
前置通知永远都会在切⼊点⽅法(业务核⼼⽅法)执⾏之前执⾏。
细节
前置通知可以获取切⼊点⽅法的参数,并对其进⾏增强。

 

  • 正常执⾏时通知
配置⽅式
 <!--
 作⽤:
 ⽤于配置正常执⾏时通知
 出现位置:
 它只能出现在aop:aspect标签内部
 属性:
 method:⽤于指定后置通知的⽅法名称
 pointcut:⽤于指定切⼊点表达式
 pointcut-ref:⽤于指定切⼊点表达式的引⽤
 -->
 <aop:after-returning method="afterReturningPrintLog" pointcutref="pt1"></aop:after-returning>
  • 异常通知
配置⽅式
<!--
 作⽤:
 ⽤于配置异常通知。
 出现位置:
 它只能出现在aop:aspect标签内部
 属性:
 method:⽤于指定异常通知的⽅法名称
 pointcut:⽤于指定切⼊点表达式
 pointcut-ref:⽤于指定切⼊点表达式的引⽤
 
 -->
 <aop:after-throwing method="afterThrowingPrintLog" pointcut-ref="pt1"
></aop:after-throwing>
执⾏时机
异常通知的执⾏时机是在切⼊点⽅法(业务核⼼⽅法)执⾏产⽣异常之后,异常通知执⾏。如果切
⼊点⽅法执⾏没有产⽣异常,则异常通知不会执⾏。
细节
异常通知不仅可以获取切⼊点⽅法执⾏的参数,也可以获取切⼊点⽅法执⾏产⽣的异常信息。
  • 最终通知
配置⽅式
<!--
 作⽤:
 ⽤于指定最终通知。
 出现位置:
 它只能出现在aop:aspect标签内部
 属性:
 method:⽤于指定最终通知的⽅法名称
 pointcut:⽤于指定切⼊点表达式
 pointcut-ref:⽤于指定切⼊点表达式的引⽤
-->
<aop:after method="afterPrintLog" pointcut-ref="pt1"></aop:after>
执⾏时机
最终通知的执⾏时机是在切⼊点⽅法(业务核⼼⽅法)执⾏完成之后,切⼊点⽅法返回之前执⾏。
换句话说,⽆论切⼊点⽅法执⾏是否产⽣异常,它都会在返回之前执⾏。
细节
最终通知执⾏时,可以获取到通知⽅法的参数。同时它可以做⼀些清理操作。
 
  • 环绕通知
配置⽅式
 <!--
 作⽤:
 ⽤于配置环绕通知。
 出现位置:
 它只能出现在aop:aspect标签的内部
 属性:
 method:⽤于指定环绕通知的⽅法名称
 pointcut:⽤于指定切⼊点表达式
 pointcut-ref:⽤于指定切⼊点表达式的引⽤
 
 -->
<aop:around method="aroundPrintLog" pointcut-ref="pt1"></aop:around>
**特别说明**
 
环绕通知,它是有别于前⾯四种通知类型外的特殊通知。前⾯四种通知(前置,后置,异常和最终)
它们都是指定何时增强的通知类型。⽽环绕通知,它是Spring框架为我们提供的⼀种可以通过编码的
⽅式,控制增强代码何时执⾏的通知类型。它⾥⾯借助的ProceedingJoinPoint接⼝及其实现类,
实现⼿动触发切⼊点⽅法的调⽤。
 
**ProceedingJoinPoint接⼝介绍**
 
类视图:
 
![image-20191205141201938]
(Spring%E9%AB%98%E7%BA%A7%E6%A1%86%E6%9E%B6%E8%AF%BE%E7%A8%8B%E8%AE%B2%E4%
B9%89.assets/image-20191205141201938.png)

4.2 XML+注解模式

  • XML 中开启 Spring 对注解 AOP 的⽀持
<!--开启spring对注解aop的⽀持-->
<aop:aspectj-autoproxy/>
  • 示例
/**
* 模拟记录⽇志
* @author 应癫
*/
@Component
@Aspect
public class LogUtil {
 /**
 * 我们在xml中已经使⽤了通⽤切⼊点表达式,供多个切⾯使⽤,那么在注解中如何使⽤呢?
 * 第⼀步:编写⼀个⽅法
 * 第⼆步:在⽅法使⽤@Pointcut注解
 * 第三步:给注解的value属性提供切⼊点表达式
 * 细节:
 * 1.在引⽤切⼊点表达式时,必须是⽅法名+(),例如"pointcut()"。
 * 2.在当前切⾯中使⽤,可以直接写⽅法名。在其他切⾯中使⽤必须是全限定⽅法名。
 */
 @Pointcut("execution(* com.lagou.service.impl.*.*(..))")
 public void pointcut(){}
 @Before("pointcut()")
 public void beforePrintLog(JoinPoint jp){
 Object[] args = jp.getArgs();
 System.out.println("前置通知:beforePrintLog,参数是:"+
Arrays.toString(args));
 }
 @AfterReturning(value = "pointcut()",returning = "rtValue")
 public void afterReturningPrintLog(Object rtValue){
 System.out.println("后置通知:afterReturningPrintLog,返回值
是:"+rtValue);
 }
 @AfterThrowing(value = "pointcut()",throwing = "e")
 public void afterThrowingPrintLog(Throwable e){
 System.out.println("异常通知:afterThrowingPrintLog,异常是:"+e);
 }
 @After("pointcut()")
 public void afterPrintLog(){
 System.out.println("最终通知:afterPrintLog");
 }
 /**
 * 环绕通知
 * @param pjp
 * @return
 */
 @Around("pointcut()")
 public Object aroundPrintLog(ProceedingJoinPoint pjp){
 //定义返回值
 Object rtValue = null;
 try{
 //前置通知
 System.out.println("前置通知");
 //1.获取参数
 Object[] args = pjp.getArgs();
//2.执⾏切⼊点⽅法
 rtValue = pjp.proceed(args);
 //后置通知
 System.out.println("后置通知");
 }catch (Throwable t){
 //异常通知
 System.out.println("异常通知");
 t.printStackTrace();
 }finally {
 //最终通知
 System.out.println("最终通知");
 }
 return rtValue;
 }
}

4.3 注解模式

在使⽤注解驱动开发 aop 时,我们要明确的就是,是注解替换掉配置⽂件中的下⾯这⾏配置
<!--开启spring对注解aop的⽀持-->
<aop:aspectj-autoproxy/>
在配置类中使⽤如下注解进⾏替换上述配置
/**
* @author 应癫
*/
@Configuration
@ComponentScan("com.lagou")
@EnableAspectJAutoProxy //开启spring对注解AOP的⽀持
public class SpringConfiguration {
}

第5节 Spring 声明式事务的⽀持

编程式事务: 在业务代码中添加事务控制代码,这样的事务控制机制就叫做编程式事务
声明式事务: 通过 xml 或者注解配置的⽅式达到事务控制的⽬的,叫做声明式事务

5.1 事务回顾

5.1.1 事务的概念

事务指逻辑上的⼀组操作,组成这组操作的各个单元,要么全部成功,要么全部不成功。从⽽确保了数据的准确与安全。
例如: A——B 转帐,对应于如下两条 sql 语句 :
 /*转出账户减钱*/
 update account set money=money-100 where name=‘a’;
 /**转⼊账户加钱*/
 update account set money=money+100 where name=‘b’;
这两条语句的执⾏,要么全部成功,要么全部不成功。

5.1.2 事务的四⼤特性

  • 原⼦性(Atomicity) 原⼦性是指事务是⼀个不可分割的⼯作单位,事务中的操作要么都发⽣,要么都 不发⽣。 从操作的⻆度来描述,事务中的各个操作要么都成功要么都失败
  • ⼀致性(Consistency) 事务必须使数据库从⼀个⼀致性状态变换到另外⼀个⼀致性状态。例如转账前A有1000,B有1000。转账后A+B也得是2000。⼀致性是从数据的⻆度来说的,(1000,1000) (900,1100),不应该出现(900,1000)
  • 隔离性(Isolation) 事务的隔离性是多个⽤户并发访问数据库时,数据库为每⼀个⽤户开启的事务,每个事务不能被其他事务的操作数据所⼲扰,多个并发事务之间要相互隔离。 如:事务1给员⼯涨⼯资2000,但是事务1尚未被提交,员⼯发起事务2查询⼯资,发现⼯资涨了2000块钱,读到了事务1尚未提交的数据(脏读)
  • 持久性(Durability) 持久性是指⼀个事务⼀旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发⽣故障也不应该对其有任何影响。

5.1.3 事务的隔离级别

不考虑隔离级别,会出现以下情况:(以下情况全是错误的),也即为隔离级别在解决事务并发问题
脏读:⼀个线程中的事务读到了另外⼀个线程中 未提交 的数据。
不可重复读:⼀个线程中的事务读到了另外⼀个线程中已经提交的 update 的数据(前后内容不⼀样)
场景:
员⼯ A 发起事务 1 ,查询⼯资,⼯资为 1w ,此时事务 1 尚未关闭
财务⼈员发起了事务 2 ,给员⼯ A 张了 2000 块钱, 并且提交了事务
员⼯ A 通过事务 1 再次发起查询请求,发现⼯资为 1.2w ,原来读出来 1w 读不到了,叫做不可重复读
虚读(幻读):⼀个线程中的事务读到了另外⼀个线程中已经提交的 insert 或者 delete 的数据(前后条数不⼀样)
场景:
事务 1 查询所有⼯资为 1w 的员⼯的总数,查询出来了 10 个⼈,此时事务尚未关闭
事务 2 财务⼈员发起,新来员⼯,⼯资 1w ,向表中插⼊了 2 条数据, 并且提交了事务
事务 1 再次查询⼯资为 1w 的员⼯个数,发现有 12 个⼈,⻅了⻤了
 
数据库共定义了四种隔离级别:
Serializable (串⾏化):可避免脏读、不可重复读、虚读情况的发⽣。(串⾏化) 最⾼
Repeatable read (可重复读):可避免脏读、不可重复读情况的发⽣。 ( 幻读有可能发⽣ ) 第⼆,该机制下会对要update 的⾏进⾏加锁
Read committed (读已提交):可避免脏读情况发⽣。不可重复读和幻读⼀定会发⽣。 第三
Read uncommitted (读未提交):最低级别,以上情况均⽆法保证。 ( 读未提交 ) 最低
注意:级别依次升⾼,效率依次降低
MySQL 的默认隔离级别是: REPEATABLE READ
查询当前使⽤的隔离级别: select @@tx_isolation;
设置 MySQL 事务的隔离级别: set session transaction isolation level xxx; (设置的是当前mysql连接会话的,并不是永久改变的)
 

5.1.4 事务的传播⾏为

事务往往在 service 层进⾏控制,如果出现 service 层⽅法 A 调⽤了另外⼀个 service 层⽅法 B , A 和 B ⽅法本身都已经被添加了事务控制,那么A 调⽤ B 的时候,就需要进⾏事务的⼀些协商,这就叫做事务的传播⾏为。
A 调⽤ B ,我们站在 B 的⻆度来观察来定义事务的传播⾏为

5.2 Spring中事务的API

mybatis: sqlSession.commit();
hibernate: session.commit();
PlatformTransactionManager
public interface PlatformTransactionManager {
 /**
* 获取事务状态信息
 */
 TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
throws TransactionException;
 /**
 * 提交事务
 */
 void commit(TransactionStatus status) throws TransactionException;
 /**
 * 回滚事务
 */
 void rollback(TransactionStatus status) throws TransactionException; }

作⽤

此接⼝是 Spring 的事务管理器核⼼接⼝。 Spring 本身并不⽀持事务实现,只是负责提供标准,应⽤底层⽀持什么样的事务,需要提供具体实现类。此处也是策略模式的具体应⽤。在Spring 框架中,也为我们内置了⼀些具体策略,例如:DataSourceTransactionManager , HibernateTransactionManager 等等。( 和 HibernateTransactionManager 事务管理器在 spring-orm-5.1.12.RELEASE.jar 中)
Spring JdbcTemplate (数据库操作⼯具)、 Mybatis ( mybatis-spring.jar ) ————> DataSourceTransactionManager
Hibernate 框架 ——————> HibernateTransactionManager DataSourceTransactionManager 归根结底是横切逻辑代码,声明式事务要做的就是使⽤ Aop (动态代理)来将事务控制逻辑织⼊到业务代码

5.3 Spring 声明式事务配置

  • 纯xml模式
  • 导⼊jar
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-context</artifactId>
 <version>5.1.12.RELEASE</version>
</dependency> <dependency>
 <groupId>org.aspectj</groupId>
 <artifactId>aspectjweaver</artifactId>
 <version>1.9.4</version>
</dependency> <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-jdbc</artifactId>
 <version>5.1.12.RELEASE</version>
</dependency> <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-tx</artifactId>
 <version>5.1.12.RELEASE</version>
</dependency>
  • xml 配置
<tx:advice id="txAdvice" transaction-manager="transactionManager">
 <!--定制事务细节,传播⾏为、隔离级别等-->
 <tx:attributes>
 <!--⼀般性配置-->
 <tx:method name="*" read-only="false"
propagation="REQUIRED" isolation="DEFAULT" timeout="-1"/>
 <!--针对查询的覆盖性配置-->
 <tx:method name="query*" read-only="true"
propagation="SUPPORTS"/>
 </tx:attributes>
 </tx:advice>
 <aop:config>
 <!--advice-ref指向增强=横切逻辑+⽅位-->
 <aop:advisor advice-ref="txAdvice" pointcut="execution(*
com.lagou.edu.service.impl.TransferServiceImpl.*(..))"/>
 </aop:config>
  • 基于XML+注解
  • xml配置
<!--配置事务管理器-->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManage
r">
 <property name="dataSource" ref="dataSource"></property>
</bean>
<!--开启spring对注解事务的⽀持-->
<tx:annotation-driven transaction-manager="transactionManager"/>
  • 在接⼝、类或者⽅法上添加@Transactional注解
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
  • 基于纯注解

Spring基于注解驱动开发的事务控制配置,只需要把 xml 配置部分改为注解实现。只是需要⼀个注解替换掉xml配置⽂件中的 <tx:annotation-driven transactionmanager="transactionManager"/> 配置。 在 Spring 的配置类上添加 @EnableTransactionManagement 注解即可

@EnableTransactionManagement//开启spring注解事务的⽀持
public class SpringConfiguration {
}

更多关于Java集合、JVM、多线程并发、spring原理、微服务、Netty 与RPC 、Kafka、日记、设计模式、Java算法、数据库、Zookeeper、分布式缓存、数据结构面试解析等等可以去这个Github链接地址:

https://github.com/ThinkingHan/Java-note 阅读,Star一下吧,感谢支持~

spring高级源码笔记:深入理解阿里spring源码核心思想及框架应用 一,spring概述 Spring 简介 Spring 是分层的 full-stack(全栈) 轻量级开源框架,以 IoC 和 AOP 为内核,提供了展现层 SpringMVC 和业务层事务管理等众多的企业级应⽤技术,还能整合开源世界众多著名的第三⽅框架和类库,已经成为使⽤最多的 Java EE 企业应⽤开源框架。 我们经常说的 Spring 其实指的是Spring Framework(spring 框架)。 本篇文章主要内容会有Spring 概述(基本情况),核⼼思想 IoC 和 AOP, 阅读详情

相关推荐

深度剖析Spring AOP源码,图文详解,小白也能看明白。

AOP 的全称是 “Aspect Oriented Programming”,即⾯向切⾯编程。在 AOP 的思想⾥⾯,周边功能(⽐如性能统计,⽇志,事务管理等)被定义为切⾯,核⼼功能和切⾯功能分别独 ⽴进⾏开发,然后把核⼼功能和切⾯功能“编织”在⼀起,这就叫 AOP。AOP 能够将那些与业务⽆关,却为业务模块所共同调⽤的逻辑封装起来,便于减少系统的重复代码,降低模块间的 耦合度,并有利于未来的可拓展性和可维护性。我们再⼩节⼀下,⽂章先介绍了什么是 AOP,以及 AOP 的原理和示例。

Java技术攻略的博客 2618

Spring-前置和后置处理器

Spring 框架中,前置和后置处理器用来Bean的创建过程中进行增强和定制,可以再Bean的初始化前后插入自己的定制的逻辑。

2302_79529958的博客 3641

spring简单前置通知、后置处理。

NULL 博文链接:https://java-frog.iteye.com/blog/325364

攀登Spring珠穆朗玛峰:前置与后置处理器

Spring前置后置处理器

肃林的博客 3848

Spark Graphx 项目实战(航班飞行网图分析)

航班飞行网图分析一.需要的技能点二.任务描述三.数据探索1.下载数据2.数据格式四.航班飞行网图问题分析1.构建航班飞行网图2.统计航班飞行网图中机场与航线的数量3.计算最长的飞行航线4.找出最繁忙的机场5.找出最重要的飞行航线6.找出最便宜的飞行航线五.代码实现 一.需要的技能点 Spark GraphX API Spark GraphX PageRank Spark GraphX Pregel 二.任务描述 需求概述: 探索航班飞行网图数据 构建航班飞行网图 使用Spark GraphX完成下列任

May_J_Oldhu的博客 1538

MDK开发篇:基于立创逻辑派FPGA-G1与Cortex-M1软核的按键控制LED实战

本文详细介绍了基于立创逻辑派FPGA-G1开发板与高云Cortex-M1软核的完整开发流程。通过Gowin云源软件配置软核系统与GPIO外设,并在Keil MDK环境中编写按键控制LED的C程序,最终实现程序固化与上电自启动。教程涵盖硬件配置、软件开发、在线调试与固化部署全步骤,帮助STM32开发者快速上手FPGA软核开发。

weixin_42103128的博客 148

手写Spring-第六章-让我访问!实现前置后置处理扩展功能

上一次我们实现了bean定义的自动化注册,这让我们的demo看起来已经很有Spring的那个味道了。但是扩展性还是差了一些。我们都知道,要写出高内聚,低耦合,富有扩展性的代码。那么如何增加扩展性呢?想想Spring中的AOP吧。在我们使用切面的时候,是不是可以在方法执行的前后进行拦截,加入我们自己的逻辑?这就是一种扩展性。它可以让我们在不修改主体逻辑的前提下,完成一些功能的扩展。那么我们这次要做的,虽然不是AOP,但思想和这个是类似的。

Forget_Re的博客 888

基于PLC的图书馆机器人设计与仿真

本文设计了一种基于PLC的图书馆机器人系统,该系统能提升图书馆自动化管理水平,选用西门子S7-1200系列PLC作为核心控制单元,结合电机驱动、传感器采集以及超声波避障等技术,设计出机器人行走、图书识别与分拣的功能模块,系统借助条形码扫描模块获取图书信息,将其分析后与设定的存放位置做对比,精准达成图书的存取和归还。仿真结果显示,机器人执行任务时运动控制响应时间是0.35秒,避障成功率为98.3%,图书识别准确率高达99.4%,在控制系统方面,运用STEP7-MICRO/WIN软件编程,结合WINCC设计组态

weixin_44553616的博客 1924

探秘Spring(1)——Bean的生命周期

探秘Spring(1)——Bean的生命周期 文章目录探秘Spring(1)——Bean的生命周期前言一、Spring的Bean是什么?二、Bean的生命周期1.实例化2.回调Aware接口3.执行初始化4.销毁总结 前言 对于做java开发的程序员来说,spring技术栈已作为必须要掌握,熟知的内容,无论是在工作还是面试中,特别是去大厂进行面试时,更是必问的问题,本系列文章主要从源码级别来探秘spring的工作原理以及所使用的设计模式。 本篇文章主要探讨Spring的重要组件Bean,包含Bean的

qq_20221431的博客 402

QT+QTimer+QThread实现线程内的定时任务并且和主线程进行交互

在制作qt软件时,我们经常会用到qtimer定时器以及将其在非主线程中进行使用,甚至有的时候还需要和主线程进行交互。我总结了两种用法,仅供参考。以上即为QTimer和QThread联合使用的学习记录。

u011826081的博客 5685

ICC2 user guide(二)Placement and Optimization

ICC2 place阶段user guide

m0_61544122的博客 9226

手写Spring高级源码(四):Spring IOC 应⽤

第四部分 Spring IOC 应⽤ 第1节 Spring IoC基础 1.1 BeanFactory与ApplicationContext区别 BeanFactory是Spring框架中IoC容器的顶层接⼝,它只是⽤来定义⼀些基础功能,定义⼀些基础规范,⽽ApplicationContext是它的⼀个⼦接⼝,所以ApplicationContext是具备BeanFactory提供的全部功能 的。 通常,我们称BeanFactory为SpringIOC的基础容器,ApplicationCon

mifffy_java的博客 384

Linux 下安装 openjdk 17【详细步骤】

JDK17,安装教程。

甘蓝的专栏 7506

深入理解 Spring AOP 源码分析(附源码分析)

Spring AOP 是一个非常常见的概念,使用了 Spring 的项目大多数也都用了 Spring AOP 的功能,比如我们常见的日志统计、事务管理等,AOP 的全称是 “Aspect Oriented Programming”,也是我们常说的⾯向切⾯编程,那你真的了解 Spring AOP 的原理吗?

weixin_42118323的博客 2351

嵌入式SDIO 总线面试题及参考答案

SDIO 的 4 位总线模式是一种提高数据传输效率的工作模式。在传统的 1 位总线模式下,数据只能通过一根数据线(DAT0)进行传输,这限制了数据传输的带宽和速度。而在 4 位总线模式下,DAT0 - DAT3 这 4 根数据线同时用于数据传输,相当于在同一时间内可以传输 4 倍于 1 位模式的数据量,从而显著提高了数据传输的带宽和速度。要通过 CMD6 命令将 SDIO 总线从当前模式切换到 4 位总线模式,需要遵循以下步骤:第一步,主设备需要确保 SDIO 卡支持 4 位总线模式。

大模型大数据攻城狮的专栏 1719

[xboard-ok210] 44 s5pv210开发板介绍和对比

文章目录前言四大S3C6410提供商友坚开发板UT-S5PV210华天正(润尔)real210飞凌开发板ok210九鼎x210友善之臂开发板tiny210mini210smart210天嵌开发板tq210sate210xboardxboardxboard之ok210 前言 四大S3C6410提供商 友坚开发板 UT-S5PV210 华天正(润尔) real210 飞凌开发板 ok210 九鼎 x210 友善之臂开发板 tiny210 mini210 smart210 天嵌开发板 tq210 sate210

鹰之翔 286

Spring AOP高级应用与源码剖析

本文介绍了Spring AOP的核心概念和高级应用。主要内容包括:1. AOP本质及术语解释(连接点、切入点、通知等);2. Spring AOP代理选择机制(JDK/CGLIB);3. XML和注解两种配置方式实现AOP;4. 五种通知类型(前置、后置、异常、最终、环绕)及其配置;5. 声明式事务的四大特性(ACID)和七种传播行为;6. 事务隔离级别及解决方案;7. 三种事务配置方式(纯XML、XML+注解、纯注解)。文章详细阐述了如何在Spring框架中实现面向切面编程和事务管理。

guslegend的博客 1001

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

【Spring Boot】Spring AOP 快速上手指南:开启面向切面编程新旅程

本期主要讲解了关于Spring AOP入门概念,以及快速入门,以及Spring AOP的代码的详细介绍:切点,连接点,通知,以及切面的概念,还有通知类型等其他注解的介绍~~~

GGBond778的博客 5648

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Spring框架及源码学习---手写IOC和AOP

Spring 是分层的 full-stack(全栈) 轻量级开源框架,以 IoC 和 AOP 为内核,提供了展现层 Spring MVC 和业务层事务管理等众多的企业级应⽤技术,还能整合开源世界众多著名的第三⽅框架和类库,已 经成为使⽤最多的 Java EE 企业应⽤开源框架。我们经常说的 Spring 其实指的是Spring Framework(spring 框架)。==IoC Inversion of Control (控制反转/反转控制),注意它是⼀个技术思想,不是⼀个技术实现 ==

weixin_43811057的博客 1217

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

详解Spring AOP篇三

详解代理模式,静态代理,JDK动态代理,CGLIB动态代理以及Spring AOP源码解析。

. 8876

Spring AOP 源码剖析

Spring AOP通过动态代理技术提供了一种灵活的方式来增强现有方法的功能,而无需修改源代码。其源码实现涉及Bean生命周期管理、动态代理技术、责任链模式等多个方面,深入理解这些机制有助于更好地使用和维护Spring AOP。

LHY537200的博客 1525

spring框架高级编程 pdf_啃完这份宝藏级“Spring高级源码笔记”,面试P7问源码还会心虚?...

前言Spring是分层的full-stack(全栈)轻量级开源框架,以IOC和APO和内核,提供了展现层SpringMVC和业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,已经成为使用最多的JavaEE企业应用开源框架。而我们经常说的Spring其实指的是Spring Framework(Spring框架)。今天咱们来分享个《Spring高级源码笔记》,总共包含七...

weixin_39968861的博客 438
上一篇: 肝了十天半月,献上纯手绘“Spring/Cloud/Boot/MVC”全家桶思维脑图,全在这儿了!
下一篇: JVM/并发/MySQL/Java/网络/Redis/Linux等一个都没“肝”完,想挤BAT你说难不难?
加班不秃顶
博客等级 码龄7年 1822粉丝 599原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值