• Spring4实现AOP


    AOP又称面向切面编程,可以不变改变原有业务的基础上进行功能的扩展,例如我们声明一个service类来处理servlet传过来的数据,每一次调用service中的验证登录信息方法的时候的都要进行日志的记录,在不改变该验证方法的基础上,我们可以利用AOP思想借助spring的提供的类,进行面向切面编程,将该方法当作切点,配置前置通知和后置通知。

    一、需要的包
    )
    二、Schema-based实现方式
    1、先声明一个类实现接口

    1. 前置通知实现MethodBeforeAdvice接口(所在包:org.springframework.aop.MethodBeforeAdvice)
    2. 后置通知实现AfterReturningAdvice接口(所在包:org.springframework.aop.AfterReturningAdvice)
    3. 实现接口的未实现方法2、实现接口中各方法的参数说明

    2、实现接口中未实现的方法进行

    public class MyBeforeAdvice implements MethodBeforeAdvice {
    	@Override
    	public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
    		System.out.println("执行前置切面");		
    	}
    }
    

    参数说明:

    1. arg0: 切点方法返回值
    2. arg1:切点方法对象
    3. arg2:切点方法参数
    4. arg3:切点方法所在类的对象

    3、applicationContext.xml进行配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop.xsd">
    <bean id="mybefor" class="com.hpu.tadvice.MyBeforeAdvice"></bean>
    <!-- 通知类 -->
    	<bean id="demo" class="com.hpu.test.Demo"></bean>
    	<aop:config>
    	   <aop:pointcut expression="execution(* com.hpu.test.Demo.demo2())" id="mypoint"/>
    	   <aop:advisor advice-ref="mybefor" pointcut-ref="mypoint"/>
    	</aop:config>
    	
    </beans>
    
    1. <aop:pointcut expression=“execution(* com.hpu.test.Demo.demo2())” id=“mypoint”/>配置切点
    2. <aop:advisor advice-ref=“mybefor” pointcut-ref=“mypoint”/>通知类配置
    3. 注意 * 通配符,匹配任意方法名,任意类名,任意一级包名
    4. 如果希望匹配任意方法参数 (…)

    4、测试代码

    package com.hpu.test;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Test {
    	public static void main(String[] args) {
         ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContextl.xml");
    	 Demo bean = ac.getBean("demo",Demo.class);
    	 bean.demo1();
    	 bean.demo2();
    	 bean.demo3();
    	}
    }
    

    三、AspectJ 方式实现
    1、声明一个类不需要实现任何接口,可以在该类中重写前置通知方法或后置通知方法

    package com.hpu.tadvice;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    
    public class MyAdvice {
        public void mybefore(String name1,int age1){
          System.out.println("前置"+name1 );
        }
        public void mybefore1(String name1){
          System.out.println("前置:"+name1);
        }
        public void myaftering(){
          System.out.println("后置 2");
        }
        public void myafter(){
          System.out.println("后置 1");
        }
        public void mythrow(){
          System.out.println("异常");
        }
        public Object myarround(ProceedingJoinPoint p) throws
          Throwable{
            System.out.println("执行环绕");
            System.out.println("环绕-前置");
            Object result = p.proceed();
            System.out.println("环绕后置");
            return result;
        }
    }
    

    2、配置applicationContext

    	<bean id="myadvice" class="com.hpu.tadvice.MyAdvice"></bean>
    	<aop:config>
    <!-- 	   <aop:pointcut expression="execution(* com.hpu.test.Demo.demo2())" id="mypoint"/>
    	   <aop:advisor advice-ref="mybefor" pointcut-ref="mypoint"/> -->
    	   
    	   <aop:aspect ref="myadvice">
    	      <aop:pointcut expression="execution(* com.hpu.test.Demo.demo1(String,int)) and args(name1,age1)" id="mypoint"/>
                 <aop:before method="mybefore" pointcut-ref="mypoint" arg-names="name1,age1"/>
                 <aop:after method="myafter" pointcut-ref="mypoint"  arg-names="name1,age1"/>   
    	   </aop:aspect>
    	</aop:config>
    

    标签解释

    <aop:after/> 后置通知,是否出现异常都执行
    <aop:after-returing/> 后置通知,只有当切点正确执行时执行
    <aop:after/> 和 <aop:after-returing/> 和<aop:after-throwing/>执行顺序和配置顺序有关
    execution() 括号不能扩上 args
    中间使用 and 不能使用&& 由 spring 把 and 解析成&&
    args(名称) 名称自定义的.顺序和 demo1(参数,参数)对应
    <aop:before/> arg-names=” 名 称 ” 名 称 来 源 于expression=”” 中 args(),名称必须一样
    args() 有几个参数,arg-names 里面必须有几个参数
    arg-names=”” 里面名称必须和通知方法参数名对应
    

    四、环绕通知
    1、声明一个类实现MethodInterceptor接口

    public class MyArround implements MethodInterceptor {
    
    	@Override
    	public Object invoke(MethodInvocation arg0) throws Throwable {
    		System.out.println("环绕-前置");
    		Object result = arg0.proceed();//放行,调用切点方式
    		System.out.println("环绕-后置");
    		return result;
    	}
    
    }
    

    2、applicationContext.xml

    <bean id="myarround" class="com.bjsxt.advice.MyArround"></bean>
    <aop:config>
          <aop:pointcut expression="execution(*com.bjsxt.test.Demo.demo1())" id="mypoint"/>
          <aop:advisor advice-ref="myarround" pointcut-ref="mypoint" />
    </aop:config>
    <bean id="demo" class="com.bjsxt.test.Demo"></bean>
    
  • 相关阅读:
    cocos2d-x学习笔记(贪吃蛇代码)
    jQuery中animate的height的自适应
    [Docker02]Docker_registry
    [Docker03] Deploy LNMP on Docker
    Python OS Module
    前端设计框架
    Ansible权威指南-读书笔记
    python+selenium之悠悠博客学习笔记
    jenkins入门
    sed
  • 原文地址:https://www.cnblogs.com/tuboshu/p/10752270.html
Copyright © 2020-2023  润新知