在开发中,为了给业务方法中增加日志记录,权限检查,事务控制等功能,此时我们需要在修改业务方法内添加这些零散的功能代码(横切面关注点)。
这些零散存在于业务方法中的功能代码【例如:日志记录,权限检查,事务控制】,我们称之为横切面关注点,
横切面关注点不属于业务范围,应该 从业务代码中剥离出来.

切面:把一个个的横切关注点放到某个模块中去,称之为切面。
那么每一个的切面都能影响业务的某一种功能, 切面的目的就是功能增强,
如日志切面就是一个横切关注点,应用中许多方法需要做日志记录的只需要插入日志的切面即可.

AOP 思想的原理:是动态代理Joinpoint:连接点,被拦截到需要被增强的方法。? where:去哪里做增强
? where:去哪些地方做增强
Advice:增强(通知),当拦截到 Joinpoint 之后,在方法执行的什么时机(when)做什么样(what)的增强。
? 根据时机分为:前置增强、后置增强、异常增强、最终增强、环绕增强
Aspect:切面,Pointcut+Advice,
? 去哪些地方+在什么时机+做什么增强
Target:目标对象,被代理的目标对象,委托对象。
Weaving:织入,把 Advice 加到 Target 上之后,创建出 Proxy 对象的过程。
Proxy:一个类被 AOP 织入增强后,产生的代理类 Advice(增强)执行时机,代理对象。
哪个包.哪个类.哪个方法】execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)
即 ★execution(<修饰符>? <返回类型> <声明类型>? <方法名>(<参数>) <异常>)
看具体的方法,先从方法名位置开始看):? *:匹配任何部分,但是只能表示一个单词。
? ..:可用于全限定名中和方法参数中,分别表示子包和 0 到 N 个参数。

<!-- AOP 配置:在什么地点、什么时机、做什么 --> <!-- 1、what【what(人物)】:做什么增强(关联what) --> <bean id="transactionManager" /> <aop:config proxy-target-> <!-- 属性proxy-target-class配置是否使用真实对象 --> <!-- 配置AOP切面 --> <aop:aspect ref="transactionManager"> <!-- 关联what --> <!-- 2、where【where+what(地点+人物)】:在哪些包中的哪些类中的哪些方法上做增强 --> <aop:pointcut id="txPoint" expression="execution(* com.shan.service..*Service*.*(..))"/> <!-- 3、when【when+where+what(时间+地点+人物)】:在方法执行的什么时机(在哪里where-关联pointcut)做增强 --> <aop:before method="open" pointcut-ref="txPoint"/> <aop:after-returning method="commit" pointcut-ref="txPoint"/> <aop:after-throwing method="rollback" pointcut-ref="txPoint"/> <aop:after method="close" pointcut-ref="txPoint"/> <aop:around method="aroundMethod" pointcut-ref="txPoint"/> </aop:aspect> </aop:config>被增强的方法的执行时机分为:前置增强、后置增强、异常增强、最终增强、环绕增强

public void rollback(Throwable ex) { System.out.println("回滚事务~,异常信息:" +ex.getMessage());}第一个参数//可以作为前置、后置、异常、最终增强方法的参数,**`第一个参数`** public void open(JoinPoint jp) { System.out.println("开启事务~"); System.out.println("代理对象:" +jp.getThis().getClass()); System.out.println("目标对象:" +jp.getTarget().getClass()); System.out.println("被增强方法的参数:" +Arrays.toString(jp.getArgs())); System.out.println("连接点方法的签名:" +jp.getSignature()); System.out.println("当前连接点的类型:" +jp.getKind());}参数processdingJoinpoint:是JointPoin 的子类,只能用于环绕增强,作为第一个参数
还可以调用真实对象中被增强的方法。
//调用真实对象的方法 ret = pjp.proceed();public Object aroundMethod(ProceedingJoinPoint pjp) { Object ret = null; System.out.println("开启事务~"); try { ret = pjp.proceed();//调用真实对象的方法 System.out.println("调用真实对象的方法...~"); System.out.println("提交事务~"); } catch (Throwable e) { System.out.println("回滚事务~,错误信息:" + e.getMessage()); }finally { System.out.println("关闭资源~"); } return ret; } <!-- AOP注解的解析器 --> <aop:aspectj-autoproxy/>注解@Aspect(配置一个AOP切面)配置where)配置when)@Component@Aspect //配置一个AOP切面public class TransactionManager { //where //xml:<aop:pointcut id="txPoint" expression="execution(* com.shan.service..*Service*.*(..))"/> @Pointcut("execution(* com.shan.service..*Service*.*(..))") public void txPoint() { } //@Before("txPoint()") public void open(JoinPoint jp) { System.out.println("开启事务~"); } //@AfterReturning("txPoint()") public void commit() { System.out.println("提交事务~"); } //@AfterThrowing(value="txPoint()", throwing="ex") public void rollback(Throwable ex) { System.out.println("回滚事务~,异常信息:" +ex.getMessage()); } //@After("txPoint()") public void close() { System.out.println("关闭资源~"); } @Around("txPoint()") public Object aroundMethod(ProceedingJoinPoint pjp) { Object ret = null; System.out.println("开启事务~"); try { ret = pjp.proceed();//调用真实对象的方法 System.out.println("调用真实对象的方法...~"); System.out.println("提交事务~"); } catch (Throwable e) { System.out.println("回滚事务~,错误信息:" + e.getMessage()); }finally { System.out.println("关闭资源~"); } return ret; }}本文来自博客园,作者:一乐乐,转载请注明原文链接:https://www.cnblogs.com/shan333/p/15953312.html