Spring-AOP
- AOP(面向切面)是一种编程思想是OOP(面向对象编程)的补充。
- AOP思想:采取横向抽取机制,去抽取重复的方法代码,在编译或运行时,用到需要的的地方,比如日志,事务等。
- AOP分类:一类可以对方法的参数进行拦截,一类是对方法进行拦截,SpringAOP属于后者,所以Spring的AOP是属于方法级的。
- 基于:代理模式,何为代理模式
jdk动态代理(接口)和CGLIB代理(类)
- 一些概念
Aspect :切面
Joinpoint :连接点 方法的调用
Pointcut 切入点 类或者方法名
织入(weave):将切面应用到目标对象并导致代理对象创建的过程
Advice:增强通知 即切入点要执行的代码前置,后置,环绕,异常,最终。 - Spring开发,基于Aspect XML 和 注解。
XML
public void before(JoinPoint joinPoint){
System.out.println("前置通知");
System.out.println("目标类是"+joinPoint.getTarget());
System.out.println("目标方法"+joinPoint.getSignature().getName());
}
//后置通知
public void afterReturn(){
System.out.println("后置通知 (只出现在没有发生异常)");
}
//环绕通知 常用
//需要ProceedingJoinPoint接口作为参数
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
System.out.println("环绕通知的之前部分");
Object proceed = proceedingJoinPoint.proceed();
System.out.println("环绕通知的之后部分");
return proceed;
}
//异常抛出通知
public void afterException(Throwable e){
System.out.println("异常出现之后的通知"+e.getMessage());
}
//最终通知
public void after(){
System.out.println("最终通知(不管是否发生异常)");
}
<bean id="userdao" class="dao.userDaoImpl"></bean>
<!--配置切面类-->
<bean id="myAspect" class="service.MyAspect"></bean>
<aop:config>
<aop:aspect ref="myAspect">
<!--配置切入点-->
<aop:pointcut id="myPointcut" expression="execution(* dao.userDao.test())"/>
<aop:before method="before" pointcut-ref="myPointcut"></aop:before>
<aop:after-returning method="afterReturn" pointcut-ref="myPointcut"></aop:after-returning>
<aop:around method="around" pointcut-ref="myPointcut"></aop:around>
<aop:after-throwing method="afterException" pointcut-ref="myPointcut" throwing="e"></aop:after-throwing>
<aop:after method="after" pointcut-ref="myPointcut"></aop:after>
</aop:aspect>
</aop:config>
注解(需要context 和AOP包)
@Aspect
@Component
public class MyAspectAnnotation {
@Pointcut("execution(* dao.userDaoImpl.test())")
private void myPointcut(){
}
@Before("myPointcut()")
public void before(JoinPoint joinPoint){
System.out.println("前置通知");
System.out.println("目标类是"+joinPoint.getTarget());
System.out.println("目标方法"+joinPoint.getSignature().getName());
}
//后置通知
@AfterReturning("myPointcut()")
public void afterReturn(){
System.out.println("后置通知 (只出现在没有发生异常)");
}
//环绕通知 常用
//需要ProceedingJoinPoint接口作为参数
@Around("myPointcut()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
System.out.println("环绕通知的之前部分");
Object proceed = proceedingJoinPoint.proceed();
System.out.println("环绕通知的之后部分");
return proceed;
}
//异常抛出通知
@AfterThrowing(value = "myPointcut()",throwing ="e")
public void afterException(Throwable e){
System.out.println("异常出现之后的通知"+e.getMessage());
}
//最终通知
@After("myPointcut()")
public void after(){
System.out.println("最终通知(不管是否发生异常)");
}
}
<context:component-scan base-package="service"></context:component-scan>
<context:component-scan base-package="dao"></context:component-scan>
<!--启动注解声明-->
<aop:aspectj-autoproxy />
下一篇jdbc与tx(事务)和一个切面 jdbc 事务的一个案列H