spring之AOP 面向切面编程

1.AOP(Aspect-Oriented Programming:面向切面编程):是一种编程范式,是一种新的方法论,是对传统的oop(面向对象编程)的补充。

AOP的主要编程对象是切面(Aspect),而切面模式化横切关注点。

在应用AOP编程时,仍然需要定义公共功能,但可以明确的定义这个功能在哪里,以什么方式应用,并且不必修改受影响的类。这样一来横切关注但就被模块化到特殊的对象(切面)里。

2.AOP的好处:降低模块的耦合度;使系统容易扩展;更好的代码复用性。 

3.AOP的专用术语:

spring之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)