spring之AOP 面向切面编程
1.AOP(Aspect-Oriented Programming:面向切面编程):是一种编程范式,是一种新的方法论,是对传统的oop(面向对象编程)的补充。
AOP的主要编程对象是切面(Aspect),而切面模式化横切关注点。
在应用AOP编程时,仍然需要定义公共功能,但可以明确的定义这个功能在哪里,以什么方式应用,并且不必修改受影响的类。这样一来横切关注但就被模块化到特殊的对象(切面)里。
2.AOP的好处:降低模块的耦合度;使系统容易扩展;更好的代码复用性。
3.AOP的专用术语:
其实我也不完全明白都是啥意思!嘿嘿嘿!
4.代理设计模式的原理:使用一个代理将对象包装起来,然后用该代理对象取代原始对象,任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用在原始对象上。
5.如果要使用代理类,那么在applicationContext.xml中的代码示例:
<bean id="logAspect" class="com.lh.spring.aopXml.LogAspect"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.lh.spring.aopXml.MoneyServiceImp.*(..))" id="logPointCut"/>
<aop:aspect ref="logAspect">
<aop:before method="beforeAdvice" pointcut-ref="logPointCut"/>
<aop:after method="afterAdvice" pointcut-ref="logPointCut"/>
<aop:after-returning method="afterReturningAdvice" returning="result" pointcut-ref="logPointCut" />
<aop:around method="aroundAdvice" pointcut-ref="logPointCut" />
<aop:after-throwing method="exceptionAdvice" pointcut-ref="logPointCut" throwing="e"/>
</aop:aspect>
</aop:config>
6.在主程序中使用代理类:(前置通知,后置通知,异常通知等)
public class LogAspect {
public void beforeAdvice(JoinPoint jp){
System.out.println(jp.getSignature().getName()+"-------------->这个方法开始执行");
}
public void afterAdvice(JoinPoint jp){
System.out.println(jp.getSignature().getName()+"-------------->这个方法执行完毕");
}
public void afterReturningAdvice(JoinPoint jp, Object result){
System.out.println("方法的返回值"+result);
}
public String aroundAdvice(ProceedingJoinPoint pjp){
Object returnValue =null;
System.out.println(pjp.getSignature().getName()+"-------------->这个方法开始执行");
try {
returnValue = pjp.proceed();
System.out.println("方法的返回值"+returnValue);
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(pjp.getSignature().getName()+"-------------->这个方法执行完毕");
return returnValue.toString();
}
public void exceptionAdvice(JoinPoint jp, Exception e){
System.out.println(jp.getSignature().getName()+"你的程序出现了问题"+e);
}
}
7.AOP使用注解的方式进行声明:
@Component
public class LogAspect {
@Before("execution(* com.lh.spring.sopAuto.MoneyServiceImp.*(..))")
public void beforeAdvice(JoinPoint jp){
System.out.println(jp.getSignature().getName()+"-------------->这个方法开始执行");
}
@After("execution(* com.lh.spring.sopAuto.MoneyServiceImp.*(..))")
public void afterAdvice(JoinPoint jp){
System.out.println(jp.getSignature().getName()+"-------------->这个方法执行完毕");
}
@AfterReturning("execution(* com.lh.spring.sopAuto.MoneyServiceImp.*(..))")
public void afterReturningAdvice(JoinPoint jp, Object result){
System.out.println("方法的返回值"+result);
}
@Around("execution(* com.lh.spring.sopAuto.MoneyServiceImp.*(..))")
public String aroundAdvice(ProceedingJoinPoint pjp){
Object returnValue =null;
System.out.println(pjp.getSignature().getName()+"-------------->这个方法开始执行");
try {
returnValue = pjp.proceed();
System.out.println("方法的返回值"+returnValue);
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(pjp.getSignature().getName()+"-------------->这个方法执行完毕");
return returnValue.toString();
}
8.使用注解的方式进行声明:在代理类中,切点表达式可以通过操作符&&,||,!结合起来,例:
@Pointcut("execution(* com.zzxtit.spring.aop.anno.*.deposit(..)) ||" +"execution(* com.zzxtit.spring.aop.anno.*.withdraw(..))")
9.在代理类上使用@Order注解,指定切面的优先级,否则它们的优先级是不确定的,值从0开始,越小优先级越高。
例:@Order(0)