AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,Struts2的拦截器设计就是基于AOP的思想,是个比较经典的例子。
一 AOP的基本概念
(1)Aspect(切面):通常是一个类,里面可以定义切入点和通知
(2)JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用
(3)Advice(通知):AOP在特定的切入点上执行的增强处理,有before,after,afterReturning,afterThrowing,around
(4)Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式
(5)AOP代理:AOP框架创建的对象,代理就是目标对象的加强。Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类
二 Spring AOP
Spring中的AOP代理还是离不开Spring的IOC容器,代理的生成,管理及其依赖关系都是由IOC容器负责,Spring默认使用JDK动态代理,在需要代理类而不是代理接口的时候,Spring会自动切换为使用CGLIB代理,不过现在的项目都是面向接口编程,所以JDK动态代理相对来说用的还是多一些。
三、AOP用法总结
方式一:接口
前置增强 MethodBeforeAdvice
后置增强 AfterReturningAdvice
异常抛出增强 ThrowsAdvice
环绕增强 MethodInterceptor
注意:还需要在applicationContext.xml文件中进行aop相关的配置
<aop:config>
<aop:pointcut expression="execution(public void *User())" id="addoptpointcut"/>
<aop:advisor advice-ref="logbefore" pointcut-ref="addoptpointcut" />
</aop:config>
<aop:config>
<aop:pointcut expression="execution(* spring_basic.UserService.*(..))" id="userServiceOptPointcut"/>
<!--
<aop:advisor advice-ref="exceptionAdvice" pointcut-ref="userServiceOptPointcut" />
-->
<aop:advisor advice-ref="logger" pointcut-ref="userServiceOptPointcut" />
</aop:config>
方式二:注解
前置增强 @Before("execution(* service.*.*(..))")
后置增强 @AfterReturning(pointcut="execution(* service.*.*(..))", returning="result")
异常抛出增强 @AfterThrowing(pointcut="execution(* service.*.*(..))", throwing="ex")
环绕增强 @Around("execution(* service.*.*(..))")
注意:还需要在applicationContext.xml文件中添加如下配置
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
方式三:Scheme
首先:添加普通的类,里面按要求编写方法
public class Logger {
public void before(JoinPoint jp){ }
public void after(JoinPoint jp, Object result){ }
public void aterThrowing(JoinPoint jp, Exception ex){ }
public Object aroundExecute(ProceedingJoinPoint pjp) throws Throwable{ }
}
其次:在applicationContext.xml中配置aop-aspect相关的配置
<aop:config>
<aop:pointcut expression="execution(* service.*.*(..))" id="optpointcut"/>
<aop:aspect ref="mylogger">
<aop:before method="before" pointcut-ref="optpointcut" />
<aop:after-returning method="after" returning="result" pointcut-ref="optpointcut" />
<aop:after-throwing method="aterThrowing" throwing="ex" pointcut-ref="optpointcut" />
<aop:around method="aroundExecute" pointcut-ref="optpointcut"/>
</aop:aspect>
</aop:config>