`
woshislf123
  • 浏览: 2641 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
最近访客 更多访客>>
社区版块
存档分类
最新评论

spring aop的一点东东

 
阅读更多

一、AOP 概念
Joinpoint(连接点):定义在哪里加入你的逻辑功能,对于Spring AOP,Jointpoint指的就是Method。
Advice(通知):特定的Jointpoint处运行的代码,对于Spring AOP 来讲,有Before advice、AfterreturningAdvice、ThrowAdvice、AroundAdvice(MethodInteceptor)等。
Pointcut(切入点):一组Joinpoint,就是说一个Advice可能在多个地方织入,
Aspect(切面):Advisor,需要实现的交叉功能
Weaving(织入):将Aspect加入到程序代码的过程,对于Spring AOP,由ProxyFactory或者ProxyFactoryBean负责织入动作。
Target(目标对象):这个很容易理解,就是需要Aspect功能的对象。

 

二、Spring AOP 代理原理
Spring AOP 是使用代理来完成的,Spring 会使用下面两种方式的其中一种来创建代理:
1、JDK动态代理,特点只能代理接口,性能相对较差,需要设定一组代理接口。
2、CGLIB 代理,可代理接口和类(final method除外),性能较高(生成字节码)。


三、Spring AOP 通知类型
1、BeforeAdvice:前置通知需实现MethodBeforeAdvice,但是该接口的Parent是BeforeAdvice。BeforeAdvice可 以修改目标的参数,也可以通过抛出异常来阻止目标运行
2、AfterreturningAdvice:实现AfterreturningAdvice,我们无法修改方法的返回值,但是可以通过抛出异 常阻止方法运行
3、AroundAdvice:Spring 通过实现MethodInterceptor(aopalliance)来实现包围通知,最大特点是可以修改返回值 ,当然它在方法前后都加入了自己的逻辑 代码。通过MethodInvocation.proceed()来调用目标方法 (甚至可以不调用)。
4、ThrowsAdvice:通过实现若干afterThrowing()来实现。
5、IntroductionInterceptor:Spring 的默认实现为DelegatingIntroductionInterceptor

四、Spring AOP  Advisor

把Advice和Pointcut组合到一个对象中。可以是bean里面的方法进行拦截。

接口为PointAdvisor

一般使用DefaultPointcutAdvisor就足够了,给它Advice和Pointcut。
当然如果想少写那么几行代码也可以使用 NameMatchMethodPointcutAdvisor,RegexpMethodPointcutAdvisor等。

 

BeforeAdvice

public class LoggerBeforeAdvice implements MethodBeforeAdvice {
    private Logger logger;
    public void setLogger(Logger logger) {
        this.logger = logger;
    }
    /*
     * method : 目标对象方法的镜像
     * args  :  目标对象方法的擦书
     * target: 目标对象
     * 注:此方法在目标对象方法调用前被代理对象调用
     */
    public void before(Method method, Object[] args, Object target)
            throws Throwable {   
        //调用一个织入的方面(这里是Logger)
        //完成记录日志的功能
        logger.log(method.getName() + " is invoked...");
    }
}

befor.xml

<bean id="logger" class="com.briup.aop.Logger"></bean>
<bean id="beforeAdvice" class="com.briup.aop.before.LoggerBeforeAdvice">
    <property name="logger">
        <ref bean="logger"/>
    </property>
</bean>
<!-- 目标对象 -->
<bean id="target" class="com.briup.aop.TestsServiceImpl"></bean>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <!-- 注入目标对象 -->
    <property name="target">
        <ref bean="target"/>
    </property>  
    <!-- 注入拦截器(可以注入多个拦截器) -->
    <property name="interceptorNames">
        <list>
            <value>beforeAdvice</value>
        </list>
    </property>   
    <!-- 注入代理接口 -->
    <property name="proxyInterfaces">
        <list>
            <value>com.briup.aop.ITestService</value>
        </list>
    </property>   
</bean>

 

AfterreturningAdvice

public class LoggerAfterAdvice implements AfterReturningAdvice {
    private Logger logger;
    public void setLogger(Logger logger){
        this.logger = logger;
    }       
    /*
     * returnValue:目标对象方法调用后返回值
     * method:    目标对象方法的镜像
     * args  :     目标对象方法的参数
     * target:       目标对象
     * 注:此方法在目标对象方法调用后被代理对象调用
     */
    public void afterReturning(Object returnValue, Method method, Object[] args,
            Object target) throws Throwable {       
        //调用一个织入的方面完成记录日志功能
        logger.log(method.getName()+" is invoked......" +
                "  returnValue "+ returnValue);
    }
}

after.xml

<bean id="logger" class="com.briup.aop.Logger"></bean>

<bean id="afterAdvice" class="com.briup.aop.after.LoggerAfterAdvice">
    <property name="logger">
        <ref bean="logger"/>
    </property>
</bean>

<!-- 目标对象 -->

<bean id="testTarget" class="com.briup.aop.TestServiceImpl"></bean>

<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <!-- 注入目标对象 -->
    <property name="target">
        <ref bean="testTarget"/>
    </property>
   
    <!-- 注入拦截器(可以注入多个拦截器) -->
    <property name="interceptorNames">
        <list>
            <value>afterAdvice</value>
        </list>
    </property>
   
    <!-- 注入代理接口 -->
    <property name="proxyInterfaces">
        <list>
            <value>com.briup.aop.ITestService</value>
        </list>
    </property>
</bean>

 

AroundAdvice

public class TransactionInterceptor implements MethodInterceptor {
    private Logger logger;
    public void setLogger(Logger logger) {
        this.logger = logger;
    } 
    /*
     * 注:此方法在目标对象方法调用的前后被代理对象调用
     */
    public Object invoke(MethodInvocation arg0) throws Throwable {
        Object returnValue = null;
        try{          
            /*
             * 注:这里可以调用一个织入的
             *        提供事务操作功能的方面(可以由事务管理器来完成--->看成一个织入)
             */
            logger.log("在此启动事务");      
            //调用下一个拦截器或者目标对象
            returnValue=  arg0.proceed();           
            logger.log("在次提交事务");
        }catch(Exception e){
            logger.log("在此回滚事务");
        }
        return null;
    }
}
arround.xml

<bean id="logger" class="com.briup.aop.Logger"></bean>

<bean id="transaction" class="com.briup.aop.arround.TransactionInterceptor">
    <property name="logger">
        <ref bean="logger"/>
    </property>
</bean>

<bean id="afterAdvice" class="com.briup.aop.after.LoggerAfterAdvice">
    <property name="logger">
        <ref bean="logger"/>
    </property>
</bean>

<!-- 目标对象 -->
<bean id="testTarget" class="com.briup.aop.TestServiceImpl"></bean>

<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <!-- 注入目标对象 -->
    <property name="target">
        <ref bean="testTarget"/>
    </property>
    <!-- 注入拦截器(可以注入多个拦截器) -->
    <property name="interceptorNames">
        <list>
            <value>transaction</value>
            <value>afterAdvice</value>
        </list>
    </property>
   
    <!-- 注入代理接口 -->
    <property name="proxyInterfaces">
        <list>
            <value>com.briup.aop.ITestService</value>
        </list>
    </property>
</bean>

在这里加了两个拦截器。先执行了arroundAdvice,然后是afterAdvice。

 

 

Advisor

advisor.xml

<bean id="logger" class="com.briup.aop.Logger"></bean>

<bean id="afterAdvice" class="com.briup.aop.after.LoggerAfterAdvice">
    <property name="logger">
        <ref bean="logger"/>
    </property>
</bean>

<bean id="beforeAdvice" class="com.briup.aop.before.LoggerBeforeAdvice">
    <property name="logger">
        <ref bean="logger"/>
    </property>
</bean>

<!--  Advisor -->
<bean id="afterAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
    <!-- 注入后增强拦截器 advice -->
    <property name="advice">
        <ref bean="afterAdvice"/>
    </property>
   
    <!-- 注入切入点 pointcut-->
    <property name="patterns">
        <list>
            <value>.*find.*</value><!-- .代表字符,*代表0或多个 -->
            <value>.*remove</value>
        </list>
    </property>
</bean>

<!-- advisor -->
<bean id="beforeAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor ">
    <!-- 注入前增强拦截器  advice -->
    <property name="advice">
        <ref bean="beforeAdvice"/>
    </property>
    <!-- 注入切入点 pointcut-->
    <property name="patterns">
        <list>
            <value>.*save.*</value><!-- .代表字符,*代表0或多个 -->
            <value>.*update</value>
        </list>
    </property>
</bean>

<!-- 目标对象 -->
<bean id="testTarget" class="com.briup.aop.TestServiceImpl"></bean>

<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <!-- 注入目标对象 -->
    <property name="target">
        <ref bean="target"/>
    </property>
   
    <!-- 注入拦截器(或者增强器)(可以注入多个拦截器) -->
    <property name="interceptorNames">
        <list>
            <value>beforeAdvisor</value>
            <value>afterAdvisor</value>
        </list>
    </property>   
    <!-- 注入代理接口 -->
    <property name="proxyInterfaces">
        <list>
            <value>com.briup.aop.ITestService</value>
        </list>
    </property>  
</bean>

 

最后再给个TestServiceImpl.java

public class OrderServiceImpl implements IOrderService {
    public Order find(Long id) throws OrderException {
        // TODO Auto-generated method stub
        System.out.println("find("+id+")");   
        return new Order();
    }
    public void remove(Long id) throws OrderException {
        // TODO Auto-generated method stub
        System.out.println("remove("+id+")");
    }
    public void save(Order order) throws OrderException {
        // TODO Auto-generated method stub
        System.out.println("save()");
       
    }
    public void update(Order order) throws OrderException {
        // TODO Auto-generated method stub
        System.out.println("update()");
        //throw new OrderException("更新失败");
    }
}

分享到:
评论

相关推荐

    spring aop jar 包

    Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。这个"spring aop jar 包"包含了实现这一功能所需的类和接口,...

    Spring AOP 16道面试题及答案.docx

    Spring AOP,全称为Aspect Oriented Programming,是面向切面编程的一种编程范式,它是对传统的面向对象编程(OOP)的一种补充。在OOP中,核心是对象,而在AOP中,核心则是切面。切面是关注点的模块化,即程序中的...

    简单spring aop 例子

    Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来处理系统中的交叉关注点问题,如日志、事务管理、安全性等。本示例将简要介绍如何在Spring应用中实现AOP,通过实际的...

    Spring AOP完整例子

    Spring AOP(面向切面编程)是Spring框架的核心特性之一,它允许开发者在不修改源代码的情况下,通过插入切面来增强或改变程序的行为。在本教程中,我们将深入探讨Spring AOP的不同使用方法,包括定义切点、通知类型...

    spring aop依赖jar包

    Spring AOP,全称Aspect-Oriented Programming(面向切面编程),是Spring框架的重要组成部分,它为Java应用程序提供了声明式的企业级服务,如事务管理、性能监控等。在Spring AOP中,我们可以通过定义切面(Aspect...

    spring-aop.jar各个版本

    spring-aop-1.1.1.jar spring-aop-1.2.6.jar spring-aop-1.2.9.jar spring-aop-2.0.2.jar spring-aop-2.0.6.jar spring-aop-2.0.7.jar spring-aop-2.0.8.jar spring-aop-2.0.jar spring-aop-2.5.1.jar spring-aop-...

    死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理(csdn)————程序.pdf

    Spring AOP 是一种面向切面编程的技术,它允许我们在不修改源代码的情况下,对应用程序的特定部分(如方法调用)进行增强。在 Spring 中,AOP 的实现主要依赖于代理模式,有两种代理方式:JDK 动态代理和 CGLIB 动态...

    Spring AOP面向方面编程原理:AOP概念

    ### Spring AOP面向方面编程原理:AOP概念详解 #### 一、引言 随着软件系统的日益复杂,传统的面向对象编程(OOP)逐渐暴露出难以应对某些横切关注点(cross-cutting concerns)的问题。为了解决这一挑战,面向方面编程...

    spring aop 自定义注解保存操作日志到mysql数据库 源码

    一、适合人群 1、具备一定Java编程基础,初级开发者 2、对springboot,mybatis,mysql有基本认识 3、对spring aop认识模糊的,不清楚如何实现Java 自定义注解的 ...4、spring boot,mybatis,druid,spring aop的使用

    Spring AOP实现机制

    **Spring AOP 实现机制详解** Spring AOP(面向切面编程)是Spring框架的核心特性之一,它允许程序员在不修改源代码的情况下,通过“切面”来插入额外的业务逻辑,如日志、事务管理等。AOP的引入极大地提高了代码的...

    Spring Aop四个依赖的Jar包

    Spring AOP,全称Aspect-Oriented Programming(面向切面编程),是Spring框架的一个重要模块,它通过提供声明式的方式来实现面向切面编程,从而简化了应用程序的开发和维护。在Spring AOP中,我们无需深入到每个...

    基于注解实现SpringAop

    基于注解实现SpringAop基于注解实现SpringAop基于注解实现SpringAop

    spring AOP依赖三个jar包

    Spring AOP,即Spring的面向切面编程模块,是Spring框架的重要组成部分,它允许开发者在不修改源代码的情况下,对程序进行横切关注点的处理,如日志、事务管理等。实现这一功能,主要依赖于三个核心的jar包:aop...

    spring aop 五个依赖jar

    Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来处理系统中的交叉关注点,如日志、事务管理等。在Java应用中,AOP通过代理模式实现了切面编程,使得我们可以将业务逻辑...

    spring AOP 引入jar包,spring IOC 引入Jar包

    Spring AOP 和 Spring IOC 是 Spring 框架的两个核心组件,它们对于任何基于 Java 的企业级应用开发都至关重要。Spring AOP(面向切面编程)允许开发者在不修改源代码的情况下,通过“切面”来插入新的行为或增强已...

    反射实现 AOP 动态代理模式(Spring AOP 的实现原理)

    面向切面编程(AOP)是一种编程范式,旨在将横切关注点(如日志、安全等)与业务逻辑分离,从而提高模块化。...利用Java反射机制和Spring AOP框架,开发者可以方便地实现AOP,从而提升代码的模块化和可维护性。

    小马哥讲 Spring AOP 编程思想 - API 线索图.pdf

    在讨论Spring AOP(面向切面编程)时,首先需要理解几个核心概念。Spring AOP 是Spring框架提供的一个功能模块,它允许开发者将横切关注点(cross-cutting concerns)从业务逻辑中解耦出来,通过在方法调用前后进行...

    spring aop用到jar包.rar

    Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来处理系统中的交叉关注点,如日志、事务管理、性能监控等。在使用Spring AOP时,通常需要引入特定的jar包来支持其功能。...

    spring aop 学习笔记

    Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和抽象化的方法来处理系统中的交叉关注点,如日志、事务管理、安全性等。本学习笔记将深入探讨Spring AOP的核心概念、工作原理以及实际...

Global site tag (gtag.js) - Google Analytics