Spring学习笔记04_AOP

什么是AOP?

  • AOP为Aspect Oriented Programming的缩写,即面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。
  • AOP也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

AOP 的作用及优势

  • 作用
在程序运行期间,不修改源码对已有方法进行增强。
  • 优势
减少重复代码、提高开发效率、维护方便

AOP 相关术语

Joinpoint(连接点):
所谓连接点是指那些被拦截到的点。在 spring 中,这些点指的是方法,因为 spring 只支持方法类型的
连接点。
Pointcut(切入点):
所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义。
Advice(通知/增强):
所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知。
通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知。
Introduction(引介):
引介是一种特殊的通知在不修改类代码的前提下, Introduction 可以在运行期为类动态地添加一些方
法或 Field。
Target(目标对象):
代理的目标对象。
Weaving(织入):
是指把增强应用到目标对象来创建新的代理对象的过程。
spring 采用动态代理织入,而 AspectJ 采用编译期织入和类装载期织入。
Proxy(代理):
一个类被 AOP 织入增强后,就产生一个结果代理类。
Aspect(切面):
是切入点和通知(引介)的结合。

基于XML的AOP配置

1、不同通知类型单独配置方式

a.把通知类用 bean 标签配置起来

<!-- 配置通知 --> 
<bean id="txManager" class="com.itheima.utils.TransactionManager"> 
	<property name="dbAssit" ref="dbAssit"></property>
</bean>

<!-- ============================================================= --> 
<bean id="dbAssit" class="com.itheima.dbassit.DBAssit"> 
	<property name="dataSource" ref="dataSource"></property>
	<!-- 指定 connection 和线程绑定 --> 
	<property name="useCurrentConnection" value="true"></property>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 
	<property name="driverClass" value="com.mysql.jdbc.Driver"></property> 
	<property name="jdbcUrl" value="jdbc:mysql:///spring_day02"></property> 
	<property name="user" value="root"></property> 
	<property name="password" value="1234"></property>
</bean>

b.使用 aop:config 声明 aop 配置

<aop:config>
	<!-- 配置的代码都写在此处 -->
</aop:config>

c.使用 aop:aspect 配置切面

<aop:aspect id="txAdvice" ref="txManager">
	<!--配置通知的类型要写在此处-->
</aop:aspect>

d.使用 aop:pointcut 配置切入点表达式

<aop:pointcut expression="execution(public void com.itheima.service.impl.AccountServiceImpl.transfer(java.lang.String, java.lang.String, java.lang.Float) )" 
			  id="pt1"/>
  • 切入点表达式说明

表达式语法:execution( [修饰符] 返回值类型 包名.类名.方法名(参数))
全匹配方式:d中的写法。
全通配方式:* * . . * . * (. .)
通常情况下,我们都是对业务层的方法进行增强,所以切入点表达式都是切到业务层实现类
execution(* com.itheima.service.impl . * . * (. .))

e.使用 aop:xxx 配置对应的通知类型

<--前置通知-->
<aop:before method="beginTransaction" pointcut-ref="pt1"/>
<--后置通知-->
<aop:after-returning method="commit" pointcut-ref="pt1"/>
<--异常通知-->
<aop:after-throwing method="rollback" pointcut-ref="pt1"/>
<--最终通知-->
<aop:after method="release" pointcut-ref="pt1"/>

2、利用环绕通知进行手动配置的方式

  • 通常情况下,环绕通知都是独立使用的 (环绕方法中可以包含其他四种通知方法)
<aop:config> 
	<aop:pointcut expression="execution(* com.itheima.service.impl.*.*(..))" id="pt1"/>
	<aop:aspect id="txAdvice" ref="txManager">
		<!-- 配置环绕通知 --> 
		<aop:around method="transactionAround" pointcut-ref="pt1"/>
	</aop:aspect>
</aop:config>
  • spring 框架为我们提供了一个接口:ProceedingJoinPoint(包含了所拦截方法的相关信息),它可以作为环绕通知的方法参数。在环绕通知执行时,spring 框架会为我们提供该接口的实现类对象,我们直接使用就行。
public Object transactionAround(ProceedingJoinPoint pjp) {
	//定义返回值
	Object rtValue = null;
	try {
	//获取方法执行所需的参数
	Object[] args = pjp.getArgs();
	//前置通知:开启事务
	beginTransaction();
	//执行方法
	rtValue = pjp.proceed(args);
	//后置通知:提交事务
	commit();
	}catch(Throwable e) {
	//异常通知:回滚事务
	rollback();
	e.printStackTrace();
	}finally {
	//最终通知:释放资源
	release();
	}
	return rtValue;
}

利用代码先后的执行顺序,就可以达到 间接实现多种不同的通知类型 的效果。



基于注解的 AOP 配置

1、不同通知类型单独配置方式

a.在 spring 配置文件中开启 spring 对注解 AOP 的支持

<!-- 开启 spring 对注解 AOP 的支持 --> 
<aop:aspectj-autoproxy/>

b.在配置类上声明配置方式

@Configuration
@ComponentScan(basePackages="com.itheima")
@EnableAspectJAutoProxy  //声明:不使用 XML 的配置方式
public class SpringConfiguration {
}

c.在通知类上使用@Aspect 注解声明为切面

@Component("txManager")	//将该类交给spring容器管理
@Aspect	//表明当前类是一个切面类
public class TransactionManager {
	//定义一个 DBAssit
	@Autowired
	private DBAssit dbAssit ; 
	...
}

d.指定切入点 并 在增强的方法上使用注解配置通知

//切入点表达式
@Pointcut("execution(* com.itheima.service.impl.*.*(..))")
private void pt1() {}

//前置通知
@Before("pt1()")	//注意:千万别忘了写括号
public void beginTransaction() {
	try {
	dbAssit.getCurrentConnection().setAutoCommit(false);
	} catch (SQLException e) {
	e.printStackTrace();
	} 
}
//后置通知
@AfterReturning("pt1()")
...
//异常通知
@AfterThrowing("pt1()")
...
//最终通知
@After("pt1()")
...

2、配置环绕通知

@Around("pt1()")//注意:千万别忘了写括号
public Object transactionAround(ProceedingJoinPoint pjp) {
	//定义返回值
	Object rtValue = null;
	try {
	//获取方法执行所需的参数
	Object[] args = pjp.getArgs();
	//前置通知:开启事务
	beginTransaction();
	//执行方法
	rtValue = pjp.proceed(args);
	//后置通知:提交事务
	commit();
	}catch(Throwable e) {
	//异常通知:回滚事务
	rollback();
	e.printStackTrace();
	}finally {
	//最终通知:释放资源
	release();
	}
	return rtValue; 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring是一个开源的Java框架,用于构建企业级应用程序。它提供了一种轻量级的、非侵入式的开发方式,通过依赖注入和面向切面编程等特性,简化了Java应用程序的开发过程。 以下是关于Spring学习的一些笔记: 1. IoC(控制反转):Spring通过IoC容器管理对象的创建和依赖关系的注入。通过配置文件或注解,将对象的创建和依赖关系的维护交给Spring容器来管理,降低了组件之间的耦合度。 2. DI(依赖注入):Spring通过依赖注入将对象之间的依赖关系解耦。通过构造函数、Setter方法或注解,将依赖的对象注入到目标对象中,使得对象之间的关系更加灵活和可维护。 3. AOP(面向切面编程):Spring提供了AOP的支持,可以将与业务逻辑无关的横切关注点(如日志、事务管理等)从业务逻辑中分离出来,提高了代码的可重用性和可维护性。 4. MVC(模型-视图-控制器):Spring提供了一个MVC框架,用于构建Web应用程序。通过DispatcherServlet、Controller、ViewResolver等组件,实现了请求的分发和处理,将业务逻辑和视图展示进行了分离。 5. JDBC和ORM支持:Spring提供了对JDBC和ORM框架(如Hibernate、MyBatis)的集成支持,简化了数据库访问的操作,提高了开发效率。 6. 事务管理:Spring提供了对事务的支持,通过声明式事务管理和编程式事务管理,实现了对数据库事务的控制和管理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值