AOP编程
Spring的AOP编程,指的是面向切面编程,AOP可以实现“业务代码”与“关注点代码”(所谓的关注点代码指的是重复代码)分离。
将业务代码与关注点代码分离,主要有以下几点好处:
- 关注点代码写一次即可
- 开发者只需要关注核心业务
- 运行时期,执行核心业务代码的时候,动态植入关注点代码; 【代理】
下面我们来熟悉一下以上提到的几个关键词:
AOP:(Aspect Object Programming),面向切面编程 功能:让关注点代码与业务代码分离!
关注点:重复的代码就叫做关注点代码。
切面:关注点形成的类,就叫切面(类)!面向切面编程,就是指对很多功能都有重复的代码抽取,再在运行的时候往业务方法上动态植入“切面类代码”。
切入点:执行目标对象方法,动态植入切面代码。可以通过切入点表达式,指定拦截哪些类的哪些方法; 给指定的类在运行的时候植入切面类代码。
AOP编程的实现方式分为两种:
- 通过注解的方式实现AOP编程
- 通过XML的方式实现AOP编程
注解方式实现AOP编程
主要步骤:
引入jar包(必须的包)
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文件提供。在bean.xml中引入AOP的名称空间
开启AOP注解
使用注解
下面列举几个比较有代表性的注解:
@Aspect
指定一个类为切面类
@Pointcut(“execution(* cn.zj5.e_aop_anno..(..))”)
指定切入点表达式
@Before(“pointCut_()”)
前置通知: 在目标方法之前执行
@After(“pointCut_()”)
后置通知:在目标方法之后执行(始终执行)
@AfterReturning(“pointCut_()”)
返回后通知:在执行方法结束前执行(异常不执行)
@AfterThrowing(“pointCut_()”)
异常通知: 出现异常时候执行
@Around(“pointCut_()”)
环绕通知: 环绕目标方法执行
XML方式实现AOP编程
具体步骤为:
- 引入jar包(4个aop相关的jar包)
- 引入aop的名称空间
- aop配置 a:配置切面类 (重复执行代码形成的类)
b:拦截哪些方法 / 拦截到方法后应用通知代码
XML配置的一些代码:
<!-- 切面类 -->
<bean id="aop" class="cn.zj6.f_aop_xml.Aop"></bean>
<!-- Aop配置 -->
<aop:config>
<!-- 定义一个切入点表达式: 拦截哪些方法 -->
<aop:pointcut expression="execution(* cn.zj6.f_aop_xml.*.*(..))" id="pt"/>
<!-- 切面 -->
<aop:aspect ref="aop">
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="pt"/>
<!-- 前置通知: 在目标方法调用前执行 -->
<aop:before method="begin" pointcut-ref="pt"/>
<!-- 后置通知: -->
<aop:after method="after" pointcut-ref="pt"/>
<!-- 返回后通知 -->
<aop:after-returning method="afterReturning" pointcut-ref="pt"/>
<!-- 异常通知 -->
<aop:after-throwing method="afterThrowing" pointcut-ref="pt"/>
</aop:aspect>
</aop:config>
切入点表达式:
切入点表达式可以对指定的“方法”进行拦截, 从而给指定的方法所在的类生成代理对象。
关于Aop配置的部分XML文档:
定义一个切入点表达式:
拦截哪些方法:(第一个星号表示返回值类型,cn.zj6.g_pointcut.星号.星号表示cn.zj6.g_pointcut包下的所有子包和子类,(..)表示这个类的方法)
<aop:pointcut expression="execution(* cn.zj6.g_pointcut.*.*(..))" id="pt"/>
拦截所有public方法:
<aop:pointcut expression="execution(public * *(..))" id="pt"/>
拦截所有save开头的方法:
<aop:pointcut expression="execution(* save*(..))" id="pt"/>
拦截指定类的指定方法, 拦截时候一定要定位到方法:
<aop:pointcut expression="execution(public * cn.zj6.g_pointcut.OrderDao.save(..))" id="pt"/>
拦截指定类的所有方法:
<aop:pointcut expression="execution(* cn.zj6.g_pointcut.UserDao.*(..))" id="pt"/>
拦截指定包,以及其自包下所有类的所有方法:
<aop:pointcut expression="execution(* cn..*.*(..))" id="pt"/>
多个表达式:
<aop:pointcut expression="execution(* cn.zj6.g_pointcut.UserDao.save()) || execution(* cn.zj6.g_pointcut.OrderDao.save())" id="pt"/>
<aop:pointcut expression="execution(* cn.zj6.g_pointcut.UserDao.save()) or execution(* cn.zj6.g_pointcut.OrderDao.save())" id="pt"/>
下面2个且关系的,没有意义:
<aop:pointcut expression="execution(* cn.zj6.g_pointcut.UserDao.save()) && execution(* cn.zj6.g_pointcut.OrderDao.save())" id="pt"/>
<aop:pointcut expression="execution(* cn.zj6.g_pointcut.UserDao.save()) and execution(* cn.zj6.g_pointcut.OrderDao.save())" id="pt"/>
取非值:
<aop:pointcut expression="!execution(* cn.zj6.g_pointcut.OrderDao.save())" id="pt"/>-->
<aop:pointcut expression=" not execution(* cn.zj6.g_pointcut.OrderDao.save())" id="pt"/>
切面和环绕通知:
<aop:aspect ref="aop">
<aop:around method="around" pointcut-ref="pt"/>
</aop:aspect>
Spring对jdbc的操作
Spring对jdbc提供了很好的支持。它主要体现在以下几个方面:
- Spring对C3P0连接池的支持很完善
Spring对jdbc提供了jdbcTemplate,来简化jdbc操作。jdbc Template是模板工具类,类似于DbUtils组件
使用Springjdbc的步骤:
引入jar包(4个aop相关的jar包)
spring-jdbc-3.2.5.RELEASE.jar jdbc的支持包
spring-tx-3.2.5.RELEASE.jar 事物包-