SpringAOP

Aop用于代码功能的横向扩展
schemaBased方式:
  <bean id="a" class="com.bjsxt.pojoAop.TestA"></bean>
   <!--配置扩展前的bean-->
   <bean id="before" class="com.bjsxt.adviceAop.MyBefore"></bean>
    <!--配置扩展后的bean-->
  <bean id="after" class="com.bjsxt.adviceAop.MyAfter"></bean>
    <!--配置扩展组装规则-->
        <aop:config>
            <!--指明要进行功能扩展的方法-->
            <aop:pointcut id="my" expression="execution(* com.bjsxt.pojoAop.TestA.testA())"/>
            <!--组件(配置规则)-->
            <aop:advisor advice-ref="before" pointcut-ref="my"></aop:advisor>
            <aop:advisor advice-ref="after" pointcut-ref="my"></aop:advisor>
        </aop:config>
main方法:


 public static void main(String[] args) {
        //获取Spring容器对象
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext-aop.xml");
        //获取对象完成功能开发  C为a的接口
       C c = (C) ac.getBean("a");
        c.testA();
    }

环绕通知 (用于代码量少时,方便简单):
类需要实现MethodInterceptor 接口

public class MyRound implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        //扩展前代码
        System.out.println("环绕通知---前");
        //调用原有代码--放行
        Object proceed = methodInvocation.proceed();
        //扩展后代码
        System.out.println("环绕通知---后:"+proceed);
        return proceed;
    }
}

配置文件:

 <!--环绕通知bean-->
        <bean id="round" class="com.bjsxt.advice.MyRound"></bean>
 <!--环绕通知-->
  <aop:config>
        <aop:advisor advice-ref="round" pointcut-ref="mp"></aop:advisor>
  </aop:config>

异常通知:(出现异常时才触发,类似于try catch)
写异常类,实现ThrowsAdvice 接口

public class MyThrow implements ThrowsAdvice {
    public void afterThrowing(Exception e){
        System.out.println("我是异常通知:"+e.getMessage());
    }
}

配置:

 <!--异常通知bean-->
        <bean id="throw" class="com.bjsxt.advice.MyThrow"></bean>
 <!--配置组装规则-->
        <aop:config>
            <!--异常通知-->
            <aop:advisor advice-ref="throw"  pointcut-ref="mp"></aop:advisor>
        </aop:config>
Aspect方式:

1、配置将增加的代码配置到一个类里面(无需接口)
ps:环绕通知需要加参数ProceedingJoinPoint

public class MyAdvice {
    //前置通知
        public void before(String name,int age){
            System.out.println("我是前置通知"+name+age);
        }
    //后置通知
        public void after(){
            System.out.println("我是后置通知");
        }
    //环绕通知
        public void myRound(ProceedingJoinPoint pp) throws Throwable {
            //环绕前
            System.out.println("环绕-前");
            //放行
            Object proceed = pp.proceed();
            //环绕后
            System.out.println("环绕-后");
        }
    //异常通知
        public void myThrow(Exception ex){
            System.out.println("我是异常通知:"+ex.getMessage());
        }
}

2、配置文件(使用aspect标签):

 <!--配置学生的bean-->
        <bean id="stu" class="com.bjsxt.pojo.Student"></bean>
        <!--配置通知bean-->
        <bean id="advice" class="com.bjsxt.advice.MyAdvice"></bean>
        <!--配置组装规则-->
        <aop:config>
            <aop:aspect ref="advice"><!--声明通知bean的ID-->
                <!--声明切点-->
                <aop:pointcut id="mp" expression="execution(* com.bjsxt.pojo.Student.testStudent(String,int)) and args(name,age)"/>
                <!--前置通知-->
                <aop:before method="before"  pointcut-ref="mp" arg-names="name,age"></aop:before>
                <!--后置通知-->
                <aop:after-returning method="after" pointcut-ref="mp"></aop:after-returning>
                <!--环绕通知-->
                <aop:around method="myRound" pointcut-ref="mp"></aop:around>
               <!--异常通知-->
                <aop:after-throwing method="myThrow" pointcut-ref="mp" throwing="ex"></aop:after-throwing>-->
            </aop:aspect>
        </aop:config>

ps:
1、关于后置通知:
异常后继续执行:after
异常后不执行:after-returning
2、schemaBase与Aspect的异同点:
类的创建:

  • aspect:只需要一个通知类,区分前后在aspect标签里
  • schemaBase:几个新功能几个类,前后通知通过接口判断

参数问题:

  • aspect:带参数很麻烦,需要在标签后配置类型arg-name
  • schemaBase:可以直接使用

3、多个方法需要增加相同功能时:
当某个类下的同名方法都需要增加相同的功能时:

类名.方法名(..)
<!--声明切点-->
            <aop:pointcut id="mp" expression="execution(* com.bjsxt.pojo.Student.testStudent(..))"/>

某类下所有方法时:

类名.*(..)

某包下所有类的所有方法:

包名.*.*(..)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值