Spring AOP理解

Spring的核心思想的IOC和AOP。最近学习AOP,对切面的学习有了进一步的认识。

Spring用代理类包裹切面,把他们织入到Spring管理的bean中。也就是说代理类伪装成目标类,它会截取对目标类中方法的调用,让调用者对目标类的调用都先变成调用伪装类,伪装类中就先执行了切面,再把调用转发给真正的目标bean。这样可以实现对业务代码的最小化侵入。使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性。Spring中日志记录,性能统计,安全控制,事务处理等都是通过AOP来管理的。

伪装类的实现有两种方式:1.实现和目标类相同的接口。这种兄弟模式下,spring会使用JDK的java.lang.reflect.Proxy类,它允许Spring动态生成一个新类来实现必要的接口,织入通知,并且把对这些接口的任何调用都转发到目标类。

2.生成子类调用,用子类来做为伪装类。这种父子模式下,spring使用CGLIB库生成目标类的一个子类,在创建这个子类的时候,spring织入通知,并且把对这个子类的调用委托到目标类。

相比之下,还是兄弟模式好些,能更好的实现松耦合,尤其在今天都高喊着面向接口编程的情况下,父子模式只是在没有实现接口的时候,也能织入通知,应当做一种例外。

下面看一个AOP的小应用。目的是为了在addStudent方法执行前后通过AOP来进行相关操作。

在上下文中配置aspectJ。

<aop:aspectj-autoproxy/>
//定义切面,切点。也可以通过注解来实现切面的和切点标识。
<aop:config>
        <aop:aspect id="StudentServiceAspect" ref="studentServiceAspect">
            <aop:pointcut id="businessService" expression="execution(* com.lufax.test.commen.studentService.*.*(..))"/>
            <aop:before method="doBefore" pointcut-ref="businessService"/>
            <aop:after method="doAfter" pointcut-ref="businessService"/>
            <aop:around method="doAround" pointcut-ref="businessService"/>
        </aop:aspect>
    </aop:config>

下面定义studentService的接口。

public interface StudentService {
    public void addStudent(String name);
}

studentService的实现类如下。

public class StudentServiceImp implements StudentService {

    public void addStudent(String name){
        System.out.println("----正在添加" + name+"----");
    }
}

以上接口和实现都是正常的业务逻辑。下面写切面。

public class StudentServiceAspect {
    //在业务代码执行前运行
    public void doBefore(){
        System.out.println("类名:");
        System.out.println("doBefore:开始添加学生");
    }
    //业务代码执行后运行
    public void doAfter(JoinPoint jp){
        System.out.println("doAfter:添加完毕");        //可以通过Joinpoint类来实现日志的打印。记录切点下类和方法名、参数,以便后续快速定位问题所在。
        System.out.println("[类名+"+jp.getTarget().getClass().getName()+"],"+
                           "[方法名:"+jp.getSignature().getName()+"],"+
                           "[参数:"+jp.getArgs()[0]+"]");
    }
   //环绕通知,retVal是返回值。这里为null
    public Object doAround(ProceedingJoinPoint pjp)throws Throwable{
        System.out.println("doAround:加入前");
        Object retVal= pjp.proceed();
        System.out.println(retVal);
        System.out.println("doAround:加入后");
        return retVal;
    }
}

通过注解实现。

@Aspect
public class StudentServiceAspect {

    @Before(value="execution(* com.lufax.test.commen.studentService.*.addStudent(..)) ")
    public void doBefore(){
        System.out.println("类名:");
        System.out.println("doBefore:开始添加学生");
    }

    @After(value="execution(* com.lufax.test.commen.studentService.*.addStudent(..))")
    public void doAfter(JoinPoint jp){
        System.out.println("doAfter:添加完毕");
        System.out.println("[类名+"+jp.getTarget().getClass().getName()+"],"+
                           "[方法名:"+jp.getSignature().getName()+"],"+
                           "[参数:"+jp.getArgs()[0]+"]");
    }

    @Around(value="execution(* com.lufax.test.commen.studentService.*.addStudent(..))")
    public Object doAround(ProceedingJoinPoint pjp)throws Throwable{
        System.out.println("doAround:加入前");
        Object retVal= pjp.proceed();
        System.out.println(retVal);
        System.out.println("doAround:加入后");
        return retVal;
    }
}

最后写测试类。

@Test
    public void test_AopAspectJ() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml","dataSource.xml");
        StudentService studentService = (StudentService) applicationContext.getBean("studentService");
        studentService.addStudent("张三");
    }

运行结果如下:

类名:
doBefore:开始添加学生
doAround:加入前
----正在添加张三----
doAfter:添加完毕
[类名+com.lufax.test.commen.studentService.StudentServiceImp],[方法名:addStudent],[参数:张三]
null
doAround:加入后
时间: 2024-09-26 20:13:27

Spring AOP理解的相关文章

spring aop 理解

源地址:http://www.verydemo.com/demo_c143_i20837.html 1.我所知道的aop 初看aop,上来就是一大堆术语,而且还有个拉风的名字,面向切面编程,都说是OOP的一种有益补充等等.一下子让你不知所措,心想着:怪不得很多人都和我说aop多难多难.当我看进去以后,我才发现:它就是一些Java基础上的朴实无华的应用,包括ioc,包括许许多多这样的名词,都是万变不离其宗而已. 2.为什么用aop 1就是为了方便,看一个国外很有名的大师说,编程的人都是"懒人&qu

深入理解Spring AOP之基本概念

深入理解Spring AOP之基本概念 AOP到底是什么 Spring AOP和IOC是听到的关于Spring最频繁的两个词了.现在来重点关注AOP这个词,IOC先放一边,下面这段话摘自Spring优势中关于面向切面的介绍: 面向切面--Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发.应用对象只实现它们应该做的--完成业务逻辑--仅此而已.它们并不负责(甚至是意识)其它的系统级关

Spring AOP 关键词的理解

1.如下图所示: AOP的执行就是在什么时候,什么地方,做什么. 2.关键词理解: 连接点(JoinPoint): 就是能够作为切点的一个个动作(方法),当然实际上不是所有连接点都当做切点的. 切点(Poincut):链接点中的一个或多个,切面会在这些点上来做文章(切点就是什么地方). 通知(Advice):通知是在切点上什么时候,做什么. 通知有下列几种类型:Before,After,After-returning, After-throwing,Around 切面(Aspect):切面包括切

深入理解Spring AOP之二代理对象生成

深入理解Spring AOP之二代理对象生成 spring代理对象 上一篇博客中讲到了Spring的一些基本概念和初步讲了实现方法,当中提到了动态代理技术,包含JDK动态代理技术和Cglib动态代理 动态代理这部分我有过一篇博客介绍:动态代理,想深入了解的朋友能够看一看,再回想一下,Spring中怎样区分採用JDK动态代理和CGlib动态代理: 假设目标对象的实现类实现了接口.Spring AOP 将会採用 JDK 动态代理来生成 AOP 代理类: 假设目标对象的实现类没有实现接口,Spring

如何简单理解spring aop和事务

用比喻的方法理解吧: 初学者的理解,仅仅为了个人好记 aop:由三部分组成:工具箱,工人,为工人分配工具 tx事务:由四部分组成:管理者,制度,工人,向工人通知管理制度  为什么这样理解呢?个人觉得好记: 在aop 中有切面:切面内的东西用来公共使用,类似于工具箱: ref就是这个工具箱的具体bean.. <aop:aspect id="***" ref="*****"> 切点:切点是许多符合切点表达式的东西,只要符合就可以使用公共的东西.根据表达式,挑

正确理解Spring AOP中的Around advice

Spring AOP中,有Before advice和After advice,这两个advice从字面上就可以很容易理解,但是Around advice就有点麻烦了. 乍一看好像是Before advice和After advice的组合,也就是说pointcut会在joinpoint执行前后各执行一次.但是这种理解是不正确的,如果这样理解的话,就会产生这样的疑问:spring aop Around类型为什么只执行一次 ,这个帖子是我碰巧看到. 那么怎么样理解才是正确的呢?我们来看一下Spri

Spring AOP深入理解之拦截器调用

Spring AOP深入理解之拦截器调用 Spring AOP代理对象生成回想 上一篇博客中:深入理解Spring AOP之二代理对象生成介绍了Spring代理对象是怎样生成的,当中重点介绍了JDK动态代理方式,简单回想下代理对象生成过程: 1.上面讲到了两种生成代理对象的方法,一种是通过ProxyFactory,一种是通过ProxyFactoryBean. 第一种获取比較简单,可是须要手工的进行写代码.而另外一种是通过Spring的IOC机制来控制Bean的生成. 2.不管是ProxyFact

Spring aop 原始的工作原理的理解

理解完aop的名词解释,继续学习spring aop的工作原理. 首先明确aop到底是什么东西?又如何不违单一原则并实现交叉处理呢? 如果对它的认识只停留在面向切面编程,那就脏了.从oop(Object Oriented Programming)说起,oop引入封装,多态,继承等概念建立对象层次的结构,处理公共行为属性的集合.对于一个系统而言,需要把分散对象整合到一起的时候,oop就虚了,因为这样的需求已经在对象层次之上了.如订单模块,还款模块都需要User对象配合(当然不止于User对象完成的

Spring AOP的理解

这是在网上发现的一篇关于Spring AOP编程的教程,读完这篇文章后,Spring AOP不再难以理解,因此我把它译成中文,推荐给Spring AOP的初学者. AOP正在成为软件开发的下一个圣杯.使用AOP,你可以将处理aspect的代码注入主程序,通常主程序的主要目的并不在于处理这些aspect.AOP可以防止代码混乱.  为了理解AOP如何做到这点,考虑一下记日志的工作.日志本身不太可能是你开发的主程序的主要任务.如果能将“不可见的”.通用的日志代码注入主程序中,那该多好啊.AOP可以帮