AOP设置

Spring的通知类型
Spring通知类型按切面功能调用的不同时刻,可以分为提供了5种Advice类型
• 前置通知Before advice:在某连接点之前执行的通知,但这个通知不能阻止连接点之前的执行流程(除非它抛出一个异常)。
• 后置通知After returning advice:在某连接点正常完成后执行的通知
• 异常通知After throwing advice:在方法抛出异常退出时执行的通知
• 最终通知After (finally) advice:当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)
• 环绕通知(Around Advice):包围一个连接点的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它自己的返回值或抛出异常来结束执行。

• 环绕通知是最常用的通知类型
• 推荐使用尽可能简单的通知类型来实现需要的功能
– 如果你只是需要一个方法的返回值来更新缓存,最好使用后置通知而不是环绕通知
• 用最合适的通知类型可以使得编程模型变得简单,并且能够避免很多潜在的错误

Hello AOP
1、添加jar包
IoC容器所需要的jar core beans context context-support expression
AOP : aop aspects[整合AspectJ]

使用注解开发
1、 前置通知(增强)
1.1、在配置文件打开自动组件扫描
<context:component-scan base-package=“com.yan” />
引入aop名空间以减少AOP相关配置
打开自动生成AspectJ代理: aop:aspectj-autoproxy/
1.2、定义业务bean
@Component(“helloService”)
public class HelloServImpl implements IHelloServ {
@Override
public void sayHello() {
System.err.println(“业务方法开始…”);
System.err.println("\t具体的业务逻辑处理…");
System.err.println(“业务方法结束…”);
}
1.3、定义切面类[切入点+通知]
Spring为了简化AOP编程,整合了AspectJ(需要进行静态编译)
@Aspect // 用于声明当前类是切面类
@Component//声明当前类是受管bean
public class BeforeHelloAspect {
//引入AspectJ的切入点表达式用于声明切入点 execution(返回类型 包名称.类名称.需要拦截的方法名称(参数类型列表))
//第一表示任意返回类型,第二部分com.yan.HelloServImpl.sayHello表示需要拦截HelloServImpl类中的sayHello方法,表示任意方法
//第三部分…表示任意个数的任意类型参数,如果需要指定可以使用java.lang.String
//@Before定义前置通知方法,value属性用于定义切入点表达式
@Before(value="execution(
com.yan.Impl.(…))")
public void bef()throws Exception{
System.err.println(“方法前置通知开始…”);
// System.err.println("\t调用的方法为:"+method);
// if(params!=null && params.length>0)
// for(Object temp:params)
// System.err.println("\t\t参数为:"+temp);
// System.err.println("\t所调用的目标对象为:"+obj);
System.err.println(“方法前置通知结束…”);
}
}
获取连接点的特征,例如入参、调用的方法名、目标类型等
@Aspect // 用于声明当前类是切面类
@Component//声明当前类是受管bean
public class BeforeHelloAspect {
@Before(value="execution(
com.yan.Impl.(…))")
public void bef(JoinPoint jp)throws Exception{
System.err.println(“方法前置通知开始…”);
Signature s=jp.getSignature();//获取方法签名
System.err.println("\t调用的方法为:"+s.getName());
Object[] params=jp.getArgs();//获取调用方法时的参数列表
if(params!=null && params.length>0)
for(Object temp:params)
System.err.println("\t\t参数为:"+temp);
Object obj=jp.getTarget();//获取目标对象
System.err.println("\t所调用的目标对象为:"+obj);
System.err.println(“方法前置通知结束…”);
}
}
是否可以修改传入参数
@Aspect // 用于声明当前类是切面类
@Component // 声明当前类是受管bean
public class BeforeHelloAspect {
@Before(value = “execution(* com.yan.Impl.(…))”)
public void bef(JoinPoint jp) throws Exception {
System.err.println(“方法前置通知开始…”);
Signature s = jp.getSignature();// 获取方法签名
System.err.println("\t调用的方法为:" + s.getName());
Object[] params = jp.getArgs();// 获取调用方法时的参数列表
if (params != null && params.length > 0) {
for (Object temp : params)
System.err.println("\t\t参数为:" + temp);
if (params[0] != null && params[0] instanceof StringBuilder) {
//params[0] = “xxxx”;// 修改传入参数无效,除非是原地修改
StringBuilder sb=(StringBuilder)params[0];
sb.append(“修改传入参数”);
}
}
Object obj = jp.getTarget();// 获取目标对象
System.err.println("\t所调用的目标对象为:" + obj);
System.err.println(“方法前置通知结束…”);
}
}
有没有办法决定是否执行业务处理
前置增强处理中没有办法决定后续处理是否执行,除非抛出异常可以阻止后续业务逻辑的处理

后续增强(业务逻辑正常结束后执行)
@Aspect
@Component
public class AfterHelloAspect {
// AfterReturning设置在业务处理正常结束后执行
// 切入点表达式中的com…表示的是com包及其子包
//returning属性用于定义返回值的名称,可以在方法声明中直接引用
@AfterReturning(value=“execution(* com….(…))”,returning=“obj”)
public void afterHello(JoinPoint jp,Object obj) throws Exception {
System.err.println(“后续逻辑处理开始…”);
System.err.println("\t业务处理返回值为:"+obj);
System.err.println(“后续逻辑处理结束…”);
}
}
在后续增强中修改业务返回值无效,除非原地修改

异常增强(当业务方法中异常中断时)
@Aspect
@Component
public class ExceptionHelloAspect {
//AfterThrowing用于定义出现异常后执行,但是不会消费掉异常,异常还会继续向上抛出
//属性throwing用于定义所出现的异常对象,如果需要使用则可以在方法中声明引用
@AfterThrowing(value=“execution(* *(…))”,throwing=“ex”)
public void handleError(JoinPoint jp,Throwable ex)throws Exception{
System.err.println(“异常增强开始…”);
System.err.println("\t出现的异常为:"+ex.getMessage());
System.err.println(“异常增强结束…”);
}
}

最终增强(不论业务方法是正常结束还是异常结束都会执行,类似于try/finally中的finally部分)
@Aspect
@Component
public class FinalHelloAspect {
@After(value = “execution(java.lang.String .(java.lang.String))”)
public void ff() throws Exception {
System.err.println(“最终通知…”);
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值