zoukankan      html  css  js  c++  java
  • SpringAop与AspectJ

    AspectJ

    AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法,所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。

    spring aop

    Spring提供了四种类型的Aop支持 
    * 基于经典的SpringAOP 
    * 纯POJO切面 
    * @ASpectJ注解驱动的切面 
    * 注入式AspectJ切面(其实与Spring并无多大的关系,这个就是使用AspectJ这个框架实现Aop编程)

    基于经典的SpringAop

    其使用ProxyFactoryBean创建: 
    增强(通知)的类型有: 
    前置通知:org.springframework.aop.MethodBeforeAdvice 
    后置通知:org.springframework.aop.AfterReturningAdvice 
    环绕通知:org.aopalliance.intercept.MethodInterceptor 
    异常通知:org.springframework.aop.ThrowsAdvice

    public interface IBookDao {
        public int add()
        public int delete();
    }
    
    public class BookDaoImpl implements IBookDao{
        public int add() {
            System.out.println("正在添加图书...");
            return 0;
        }
        public int delete() {
            System.out.println("正在删除图书...");
            return 0;
        }
    }
    
    //实现了MethodInterceptor的环绕增强类
    public class MyAdvice implements MethodInterceptor{
    
        public Object invoke(MethodInvocation invocation) throws Throwable {
            System.out.println("Around Advice before method invocation");
            Object o = invocation.proceed();
            System.out.println("Around Advice after method invocation");
            return o;
        }
    }
    //将每一个连接点都当做切点(拦截每一个方法)
    <bean id="bookDao" class="com.njust.learning.spring.service.BookDaoImpl"></bean>
    
        <bean id="myadvice" class="com.njust.learning.spring.aop.MyAdvice"></bean>
    
        <bean id="bookDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
            <property name="target" ref="bookDao"/>
            <property name="proxyInterfaces" value="com.njust.learning.spring.service.IBookDao"/>
            <property name="interceptorNames" value="myadvice"/>
        </bean>
    使用RegexMethodPointcutAdvisor针对某些特定的方法进行拦截增强
    <bean id="bookDao" class="com.njust.learning.spring.service.BookDaoImpl"></bean>
    
        <bean id="myadvice" class="com.njust.learning.spring.aop.MyAdvice"></bean>
    
    
        <bean id="rmpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
            <!--patterns,如果有多个指定的值的话,可以使用,隔开,例如value=".*add,.*delete"-->
            <property name="patterns" value=".*add"/>
            <property name="advice" ref="myadvice"/>
        </bean>
    <!--使用的时候使用这个id,而不是原始的那个id-->
        <bean id="bookDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
            <property name="target" ref="bookDao"/>
            <property name="proxyInterfaces" value="com.njust.learning.spring.service.IBookDao"/>
            <property name="interceptorNames" value="rmpAdvisor"/>
        </bean>
    注意

    像上面这样,每定义一个dao都需要定义一个ProxyFactoryBean,显得很麻烦,所以我们引入自动代理,也就是自动创建代理对象

    BeanNameAutoProxyCreator

    <bean id="bookDao" class="com.njust.learning.spring.service.BookDaoImpl"></bean>
    
        <bean id="myadvice" class="com.njust.learning.spring.aop.MyAdvice"></bean>
    
        <bean id="rmpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
            <!--patterns,如果有多个指定的值的话,可以使用,隔开,例如value=".*add,.*delete"-->
            <property name="patterns" value=".*add"/>
            <property name="advice" ref="myadvice"/>
        </bean>
    
        <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
            <property name="beanNames" value="*Dao"></property>
            <property name="interceptorNames" value="rmpAdvisor"></property>
        </bean>

    DefaultAdvisorAutoProxyCreator

    <bean id="bookDao" class="com.njust.learning.spring.service.BookDaoImpl"></bean>
    
        <bean id="myadvice" class="com.njust.learning.spring.aop.MyAdvice"></bean>
    
        <bean id="rmpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
            <!--patterns,如果有多个指定的值的话,可以使用,隔开,例如value=".*add,.*delete"-->
            <property name="patterns" value=".*add"/>
            <property name="advice" ref="myadvice"/>
        </bean>
    
        <!--根据切面中生成信息生成代理-->
        <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>

    纯POJO切面,需要使用XML进行配置

    public interface IBookDao {
        public int add();
        public int delete();
    }
    
    public class BookDaoImpl implements IBookDao{
    
        public int add() {
            int a = 1/0;
            System.out.println("正在添加图书...");
            return 0;
        }
    
        public int delete() {
            System.out.println("正在删除图书...");
            return 0;
        }
    }
    public class PojoAdvice {
        public void before(){
            System.out.println("前置通知");
        }
        public void after(Object returnval){
            System.out.println("后置通知"+",处理后的结果为:"+returnval);
        }
        public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            System.out.println("环绕前置增强...");
            Object o = proceedingJoinPoint.proceed();
            System.out.println("环绕后置增强...");
            return o;
        }
        public void afterThrowing(Throwable e){
            System.out.println("异常通知:"+e.getMessage());
        }
    }
    <bean id="bookDao" class="com.njust.learning.spring.service.BookDaoImpl"></bean>
    
        <bean id="pojoAdvice" class="com.njust.learning.spring.pojoaop.PojoAdvice"></bean>
    
        <aop:config>
            <aop:pointcut id="p" expression="execution (* *.add(..))"/>
            <aop:aspect ref="pojoAdvice">
                <aop:before method="before" pointcut-ref="p"></aop:before>
                <!--通过设置returning来将返回值传递给通知-->
                <aop:after-returning method="after" pointcut-ref="p" returning="returnval"/>
                <aop:around method="around" pointcut-ref="p"/>
                <!--通过设置returning来将异常对象传递给通知-->
                <aop:after-throwing method="afterThrowing" pointcut-ref="p" throwing="e"/>
            </aop:aspect>
        </aop:config>

    联系

    我们借助于Spring Aop的命名空间可以将纯POJO转换为切面,实际上这些POJO只是提供了满足切点的条件时所需要调用的方法,但是,这种技术需要XML进行配置,不能支持注解 
    所以spring借鉴了AspectJ的切面,以提供注解驱动的AOP,本质上它依然是Spring基于代理的AOP,只是编程模型与AspectJ完全一致,这种风格的好处就是不需要使用XML进行配置

    本文为学习而转载 https://blog.csdn.net/qq_21050291/article/details/72523138
  • 相关阅读:
    POJ 2027
    POJ 2017
    重定位(转载)
    常见储存器件的分辨(RAM、SRAM、SDRAM、ROM、FLASH、Nand Flash、Nor Flash、DDR、eMMC)
    虚拟机安装配置ubuntu共享文件夹
    ARM芯片时钟体系
    串行通信协议 —— UART
    串行通信协议——基础知识
    内存地址和内存空间
    中断与异常
  • 原文地址:https://www.cnblogs.com/danica/p/9406094.html
Copyright © 2011-2022 走看看