Spring之AOP面向切面编程
一,概述
1)AOP(Aspect Oriented Programming):面向切面编程,是一种可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的技术.
2)关注点代码与核心业务代码,看下面代码一看就知道区别了...
// 保存一个用户
public void add(User user) { Session session = null; Transaction trans = null; try { session = HibernateSessionFactoryUtils.getSession(); // 【关注点代码】trans = session.beginTransaction(); // 【关注点代码】session.save(user); // 核心业务代码trans.commit(); //…【关注点代码】} catch (Exception e) { e.printStackTrace(); if(trans != null){ trans.rollback(); //..【关注点代码】} } finally{ HibernateSessionFactoryUtils.closeSession(session); ..【关注点代码】} }
关注点:指重复执行的代码.
关注点代码与业务代码分离的好处?
关注点代码写一次即可:开发者只需要关注业务代码即可;运行时期,执行核心业务代码的时候动态植入关注点代码.
如何分离?
过程式/对象式/代理模式分离.
3)AOP功能:让关注点代码与核心业务代码分离.
4)切面:关注点形成的类,就叫切面(类).
面向切面编程:就是指对很多功能都有重复的代码进行抽取,再在运行的时候往业务方法上动态的植入"切面类代码".
5)切入点:执行目标对象方法,动态植入切面代码.
可以通过切入点表达式,指定拦截哪些类的哪些方法,给指定的类在运行的时候动态植入切面类代码.
二,注解方式实现AOP编程
开发步骤
1)先引入aop相关jar文件(aspectj aop优秀组件).
spring-aop-3.2.5.RELEASE.jar 【spring3.2源码】
aopalliance.jar 【spring2.5源码/lib/aopalliance】
aspectjweaver.jar 【spring2.5源码/lib/aspectj】或【aspectj-1.8.2\lib】
aspectjrt.jar 【spring2.5源码/lib/aspectj】或【aspectj-1.8.2\lib】
注意:用到spring2.5版本的jar文件,如果用jdk1.7可能会有问题.需要升级aspectj组件,即使用aspectj-1.8.2版本(或其他版本)中提供的jar文件.
2) bean.xml中引入aop名称空间.
3)开启aop注解.
4) 使用注解.
@Aspect 指定一个类为切面类
@Pointcut("execution(* com.bighuan.e_aop_anno.*.*(..))") 指定切入点表达式
@Before("pointCut_()") 前置通知: 目标方法之前执行
@After("pointCut_()") 后置通知:目标方法之后执行(始终执行)
@AfterReturning("pointCut_()") 返回后通知: 执行方法结束前执行(异常不执行)
@AfterThrowing("pointCut_()") 异常通知: 出现异常时候执行
@Around("pointCut_()") 环绕通知: 环绕目标方法执行
开发ing
1)最最重要的事:在bean.xml中开启注解扫描及AOP注解方式.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 开启注解扫描 -->
<context:component-scan base-package="com.bighuan.e_aop_anno"></context:component-scan>
<!-- 开启aop注解方式 :如果目标对象有实现接口就用JDK代理;否则就用cglib代理-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
2)接口
public interface IUserDao {void save();
}
3)目标对象,并将目标对象加入IOC容器.
@Component// 加入IOC容器
public class UserDao implements IUserDao {@Overridepublic void save() {System.out.println("***保存用户数据到数据库");}
}
4)切面类:用Aspect将Aop类声明为切面类,同时将该类加入IOC容器
@Component
@Aspect// 指定当前类为切面类
public class Aop {// @Pointcut("execution(* com.bighuan.e_aop_anno.UserDao.save(..))")@Pointcut("execution(* com.bighuan.e_aop_anno.*.*(..))")public void pointCut() {// 方法名随便}// 指定切入点表达式:拦截那些方法,即为那些类生成代理对象// @Before("execution(* com.bighuan.e_aop_anno.UserDao.save(..))")// @Before("execution(* com.bighuan.e_aop_anno.UserDao.*(..))")// public void begin(){// System.out.println("*****开启事务*****");// }// @After("execution(* com.bighuan.e_aop_anno.UserDao.*(..))")// public void commit(){// System.out.println("********提交事务******");// }// 前置通知:在执行目标方法之前执行@Before("pointCut()")public void begin() {System.out.println("*****开启事务*****");}// 后置/最终通知:在执行目标方法之后执行,无论是否出现异常最终都会执行@After("pointCut()")public void after() {System.out.println("********提交事务******");}// 执行方法结束前执行@AfterReturning("pointCut()")// 出现异常不执行public void afterReturning() {System.out.println("Aop.afterReturning()");}// 在目标方法执行异常时执行@AfterThrowing("pointCut()")public void afterThrowing() {System.out.println("Aop.afterThrowing()");}// 环绕通知@Around("pointCut()")public void around(ProceedingJoinPoint pjp) throws Throwable {System.out.println("环绕前>>>>>>>");Object returnValue = pjp.proceed();// 执行目标方法System.out.println("环绕后<<<<<<<<<<");}
}
5)测试:
private ApplicationContext ac = new ClassPathXmlApplicationContext("com/bighuan/e_aop_anno/bean.xml");//目标对象有实现接口,Spring会自动选择"JDK"代理,即动态代理@Testpublic void testAop() throws Exception {IUserDao userDao = (IUserDao) ac.getBean("userDao");System.out.println(userDao.getClass());userDao.save();}
结果:
class $Proxy12
环绕前>>>>>>>
*****开启事务*****
***保存用户数据到数据库
环绕后<<<<<<<<<<
********提交事务******
Aop.afterReturning()
从结果可以看出,这是JDK代理即动态代理.
6)OrderDao不实现接口,同样把他加入IOC容器
@Component //加入IOC容器
public class OrderDao {public void save() {System.out.println("***保存用户数据到数据库111111111111");//int i=1/0;}}
7)测试2:
//目标对象没有实现接口,Spring会自动选择"Cglib"代理,即子类代理@Testpublic void testCglib() throws Exception {OrderDao orderDao = (OrderDao) ac.getBean("orderDao");System.out.println(orderDao.getClass());orderDao.save();}
结果:
class com.bighuan.e_aop_anno.OrderDao$$EnhancerByCGLIB$$c7d2931b
环绕前>>>>>>>
*****开启事务*****
***保存用户数据到数据库111111111111
环绕后<<<<<<<<<<
********提交事务******
Aop.afterReturning()
不实现接口的话,就是Cglib代理了.
三,XML方式实现AOP编程
1)依然使用上面的IUserDao,UserDao,OrderDao,将注解全部去掉.环境也是同一个(即引入同样的jar包)
2)切面类:Aop.java
//切面类
public class Aop {public void pointCut(){//方法名随便}//指定切入点表达式:拦截那些方法,即为那些类生成代理对象
// @Before("execution(* com.bighuan.e_aop_anno.UserDao.save(..))")
// @Before("execution(* com.bighuan.e_aop_anno.UserDao.*(..))")
// public void begin(){
// System.out.println("*****开启事务*****");
// }
// @After("execution(* com.bighuan.e_aop_anno.UserDao.*(..))")
// public void commit(){
// System.out.println("********提交事务******");
// }//前置通知:在执行目标方法之前执行public void begin(){System.out.println("*****开启事务*****");}public void after(){System.out.println("********提交事务******");}public void afterReturning(){System.out.println("Aop.afterReturning()");}public void afterThrowing(){System.out.println("Aop.afterThrowing()");}public void around(ProceedingJoinPoint pjp) throws Throwable{System.out.println("环绕前>>>>>>>");Object returnValue = pjp.proceed();//执行目标方法System.out.println("环绕后<<<<<<<");}
}
3)bean.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!-- dao实例 --><bean id="userDao" class="com.bighuan.f_aop_xml.UserDao"></bean><bean id="orderDao" class="com.bighuan.f_aop_xml.OrderDao"></bean><!-- 切面类 --><bean id="aop" class="com.bighuan.f_aop_xml.Aop"></bean><!-- Aop配置 --><aop:config><!-- 定义一个切入点表达式,拦截哪些方法 --><aop:pointcut expression="execution(* com.bighuan.f_aop_xml.*.*(..))"id="pt" /><!-- 切面类 --><aop:aspect ref="aop"><!-- 前置通知:在目标方法调用前执行 --><aop:before method="begin" pointcut-ref="pt" /><!-- 后置通知:在目标方法调用后执行 --><aop:after method="after"pointcut="execution(* com.bighuan.f_aop_xml.*.*(..))" /><!-- 返回后通知 --><aop:after-returning method="afterReturning"pointcut-ref="pt" /><!--异常通知 --><aop:after-throwing method="afterThrowing"pointcut-ref="pt" /><!-- 环绕通知 --><aop:around method="around" pointcut-ref="pt" /></aop:aspect></aop:config>
</beans>
4)测试代码与上面的一样.
四,总结
XML方式更容易维护,我倾向于这种方式...
Spring之AOP面向切面编程相关推荐
- spring中AOP(面向切面编程)
spring中AOP(面向切面编程) 面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是spring框架中的一个重要内容 ...
- 大数据WEB阶段Spring框架 AOP面向切面编程(一)
Spring - AOP面向切面编程(一) 一.代理模式概述 代理的特点:(目标对象即被代理者) 实现和目标对象相同的接口 具备和目标对象的方法 代理者不仅要做目标对象的方法 , 还要做一些额外的操作 ...
- 大数据WEB阶段Spring框架 AOP面向切面编程(二)
Spring AOP面向切面编程(二) 一.切入点的execution表达式 execution的表达形式: execution(修饰符? 返回值类型 所在包类? 方法名(参数列表) 异常?) ?表示 ...
- 【SSM】Spring系列——AOP面向切面编程
文章目录 03 AOP面向切面编程 3.1 AOP概述 3.2 面向切面编程对有什么好处 3.3 模拟AOP框架实现 3.3.1 代码实现版本一 3.3.2 代码实现版本二 3.3.3 代码实现版本三 ...
- Spring框架 AOP面向切面编程(转)
一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址:http://www.cnbl ...
- Spring的AOP面向切面编程
什么是AOP? 1.AOP概念介绍 所谓AOP,即Aspect orientied program,就是面向方面(切面)的编程. 功能: 让关注点代码与业务代码分离! 关注点: 重复代码就叫做关注点: ...
- Spring Boot AOP面向切面编程使用(定义切入点、前置通知、后置通知、返回通知、异常通知、环绕通知)
1 AOP AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发 ...
- Spring之AOP(面向切面编程)_入门Demo
AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可 ...
- 【Spring】AOP面向切面编程(Spring4和Spring5区别)
AOP 1. 什么是AOP 2. AOP常用注解 3.Spring4各种通知的执行节点 4. 在aop中校验不通过如何不让程序进入核心代码? 5. 同一个方法被多个Aspect类拦截 5.1 如何指定 ...
- Spring(三)AOP面向切面编程
原文链接:http://www.orlion.ga/205/ 一.AOP简介 1.AOP概念 参考文章:http://www.orlion.ml/57 2.AOP的产生 对于如下方法: public ...
最新文章
- 每日英语:Relationship Repair: 10 Tips for Thinking Like a Therapist
- python查询文件软件_Python小工具--多文件查找字符串fs
- 如何找到 SAP Spartacus 里某个 Component TypeScript 编译后生成的 JavaScript 位置
- 【sklearn学习】模型网格化调参
- LeetCode17——Letter Combinations of a Phone Number(手机几个按键对应的字母(符号)组合)
- 使用 javascript 标记高亮关键词
- BZOJ2241 [SDOI2011]打地鼠 【模拟】
- 基于机器视觉的电阻焊接质量检测
- 机器学习概念笔记(1)——混淆矩阵、Precision、Recall、F-score
- Heartbeat实现web服务器高可用
- 谈谈如何用eoLinker管理各类API接口
- B站ACM算法资源汇总
- Nvidia 驱动的安装和卸载(Ubuntu20.04)
- 丝杠螺母传动机构设计
- python自测单词软件_还在用背单词App?使用Python开发英语单词自测工具,助你逆袭单词王!...
- amd显卡风扇调节_解决办法:设置显卡风扇速度的教程方法
- echarts柱状图加上数量
- 安卓按键精灵手机助手(功能:安卓版抓抓、命令库、制作电脑UI界面)
- Matlab基本函数-floor函数
- endnote 使用方法