复习Spring第二课--AOP原理及其实现方式

AOP原理:

AOP,面向方面的编程,使用AOP,你可以将处理方面(Aspect)的代码注入主程序,通常主程序的主要目的并不在于处理这些aspect。AOP可以防止代码混乱。AOP的应用范围包括:持久化管理(Persistent)、事务管理(Transaction Management)、安全管理(Security)、日志管理(Logging)和调试管理(Debugging)等。

AOP概念:

  — 方面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。事务管理是J2EE应用中一个很好的横切关注点例子。方面用Spring的Advisor或拦截器实现。

  — 连接点(Joinpoint):程序执行过程中明确的点,如方法的调用或特定的异常被抛出。

  — 通知(Advice):在特定的连接点,AOP框架执行的动作。各种类型的通知包括“around”、“before”和“throws”通知。通知类型将在下面讨论。许多AOP框架包括Spring都是以拦截器做通知模型,维护一个“围绕”连接点的拦截器链。

  — 切入点(Pointcut):指定一个通知将被引发的一系列连接点的集合。AOP框架必须允许开发者指定切入点,例如,使用正则表达式。

  — 引入(Introduction):添加方法或字段到被通知的类。Spring允许引入新的接口到任何被通知的对象。例如,你可以使用一个引入使任何对象实现IsModified接口,来简化缓存。

  — 目标对象(Target Object):包含连接点的对象,也被称作被通知或被代理对象。

  — AOP代理(AOP Proxy):AOP框架创建的对象,包含通知。在Spring中,AOP代理可以是JDK动态代理或CGLIB代理。

  — 编织(Weaving):组装方面来创建一个被通知对象。这可以在编译时完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。

通知类型:

  —  Around通知:包围一个连接点的通知,如方法调用。这是最强大的通知。Aroud通知在方法调用前后完成自定义的行为,它们负责选择继续执行连接点或通过返回它们自己的返回值或抛出异常来短路执行。

  —  Before通知:在一个连接点之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)。

  —  Throws通知:在方法抛出异常时执行的通知。Spring提供强制类型的Throws通知,因此你可以书写代码捕获感兴趣的异常(和它的子类),不需要从Throwable或Exception强制类型转换。

  —  After returning通知:在连接点正常完成后执行的通知,例如,一个方法正常返回,没有抛出异常。

  Around通知是最通用的通知类型。大部分基于拦截的AOP框架(如Nanning和Jboss 4)只提供Around通知。

  如同AspectJ,Spring提供所有类型的通知,我们推荐你使用最为合适的通知类型来实现需要的行为。例如,如果只是需要用一个方法的返回值来更新缓存,你最好实现一个after returning通知,而不是around通知,虽然around通知也能完成同样的事情。使用最合适的通知类型使编程模型变得简单,并能减少潜在错误。例如,你不需要调用在around通知中所需使用的MethodInvocation的proceed()方法,因此就调用失败。

  切入点的概念是AOP的关键,它使AOP区别于其他使用拦截的技术。切入点使通知独立于OO的层次选定目标。例如,提供声明式事务管理的around通知可以被应用到跨越多个对象的一组方法上。 因此切入点构成了AOP的结构要素。

AOP的实现方式主要有两种:

第一种:配置文件中配置pointcut,在java中用编写实际的aspect 类,针对切入点进行相关的业务处理。

第一步编写目标对象类

 1 package com.aop;
 2
 3 public class CommonEmployee implements Employee{
 4
 5     private String name;
 6
 7     public String getName() {
 8         return name;
 9     }
10
11     public void setName(String name) {
12         this.name = name;
13     }
14
15     public void signIn() {
16        System.out.println("打印出了:"+name);
17     }
18 }

第二步编写通知类:

 1 package com.aop;
 2
 3 import java.util.Date;
 4 import org.aspectj.lang.ProceedingJoinPoint;
 5
 6 public class Logger{
 7
 8     //spring中Before通知
 9     public void logBefore() {
10         System.out.println("logBefore");
11     }
12
13     //spring中After通知
14     public void logAfter() {
15         System.out.println("logAfter");
16     }
17
18     //spring中Around通知
19     public Object logAround(ProceedingJoinPoint joinPoint) {
20         System.out.println("logAround开始"); //方法执行前的代理处理
21         Object[] args = joinPoint.getArgs();
22         Object obj = null;
23         try {
24             obj = joinPoint.proceed(args);
25         } catch (Throwable e) {
26             e.printStackTrace();
27         }
28         System.out.println("logAround结束");  //方法执行后的代理处理
29         return obj;
30     }
31
32 }

Spring配置:

 1 <bean id="employee" class="com.aop.CommonEmployee">
 2       <property name="name" value="good"></property>
 3 </bean>
 4 <bean id="advice" class="com.aop.Logger" />
 5 <aop:config >
 6    <aop:aspect ref="advice">
 7       <aop:pointcut id="pointcut" expression="execution(*com.aop.CommonEmployee.sign*(..))"/>
 8       <aop:before method="logBefore" pointcut-ref="pointcut"/>
 9       <aop:after method="logAfter" pointcut-ref="pointcut"/>
10       <aop:around method="logAround" pointcut-ref="pointcut"/>
11     </aop:aspect>
12 </aop:config>    

编写测试类:

 1 package com;
 2
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5
 6 import com.aop.Employee;
 7
 8 public class Test {
 9     public static void main(String[] args) throws Exception{
10         ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml");
11         Employee e = (Employee)act.getBean("employee");
12         e.signIn();
13
14     }
15 }

最后结果:

logBefore

logAround开始

打印出了:good

logAfter

logAround结束

第二种方式:

采用注解来做aop, 主要是将写在spring 配置文件中的连接点, 写到注解里面。

首先,在spring配置文件中加入如下配置(用来申明spring对@AspectJ的支持):

<aop:aspectj-autoproxy/>

如果你使用的是DTD,可以在Spring配置文件中加入如下配置来申明spring对@Aspect的支持:

<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />

目标对象类与上边一样

具体通知类如下:

 1 package com.aop;
 2
 3 import java.util.Date;
 4
 5 import org.aspectj.lang.ProceedingJoinPoint;
 6 import org.aspectj.lang.annotation.After;
 7 import org.aspectj.lang.annotation.Around;
 8 import org.aspectj.lang.annotation.Aspect;
 9 import org.aspectj.lang.annotation.Before;
10
11 /**
12  * 使用@Aspect 注解的类, Spring 将会把它当作一个特殊的Bean(一个切面),也就是
13  * 不对这个类本身进行动态代理
14  */
15 @Aspect
16 public class AspectJLogger {
17     /**
18      * 必须为final String类型的,注解里要使用的变量只能是静态常量类型的
19      */
20     public static final String EDP = "execution(*com.aop.CommonEmployee.sign*(..))";
21
22     @Before(EDP)    //spring中Before通知
23     public void logBefore() {
24         System.out.println("logBefore");
25     }
26
27     @After(EDP)    //spring中After通知
28     public void logAfter() {
29         System.out.println("logAfter");
30     }
31
32     @Around(EDP)   //spring中Around通知
33     public Object logAround(ProceedingJoinPoint joinPoint) {
34         System.out.println("logAround开始"); //方法执行前的代理处理
35         Object[] args = joinPoint.getArgs();
36         Object obj = null;
37         try {
38             obj = joinPoint.proceed(args);
39         } catch (Throwable e) {
40             e.printStackTrace();
41         }
42         System.out.println("logAround结束");  //方法执行后的代理处理
43         return obj;
44     }
45 }

Spring配置

1  <aop:aspectj-autoproxy/>
2     <bean id="aspect" class="com.aop.AspectJLogger" />
3  <bean id="employee" class="com.aop.CommonEmployee">
4       <property name="name" value="good"></property>
5  </bean>

最后测试类和测试结果都一样的。

时间: 2024-12-01 19:41:33

复习Spring第二课--AOP原理及其实现方式的相关文章

Spring IOC, DI, AOP 原理和实现

介绍的比较详细(概念): http://blog.csdn.net/mdcmy/article/details/8542277 http://my.oschina.net/u/1012289/blog/136648 系统的学习: http://openhome.cc/Gossip/SpringGossip/

Jquery第二课 Javascript基础

基础知识 网页由三个部分组成:HTML.CSS和JavaScript.它们分别完成不同的功能,其中HTML描述页面内容.CSS负责内容的展示.JavaScript添加交互功能和动态效果.三者一起组成一个完整的Web页面. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>长沙戴维营教育jQuery教程 第二课</title> <!-- CS

Spring第二天——IOC注解操作与AOP概念

大致内容 spring的bean管理(注解实现) AOP原理 log4j介绍 spring整合web项目的演示 一.spring注解实现bean管理 注解: 代码中一些特殊的标记,使用注解也可以完成一些相关的功能(写法"@") 方法上.类上(详见基础加强) 使用注解创建对象,注入属性(完成day01相似的功能) 可以使用注解,但不可能完全替代xml配置文件 准备工作: 导入包:除了day01的6个核心jar包(当然包括日志的包) 再加上aop的那个jar包(注解功能在里面),也就是图中

Spring系列之AOP的原理及手动实现

目录 Spring系列之IOC的原理及手动实现 Spring系列之DI的原理及手动实现 引入 到目前为止,我们已经完成了简易的IOC和DI的功能,虽然相比如Spring来说肯定是非常简陋的,但是毕竟我们是为了理解原理的,也没必要一定要做一个和Spring一样的东西.到了现在并不能让我们松一口气,前面的IOC和DI都还算比较简单,这里要介绍的AOP难度就稍微要大一点了. tips 本篇内容难度较大,每一步都需要理清思路,可能需要多看几遍,多画类图和手动实现更容易掌握. AOP 什么是AOP Asp

spring aop 原理

http://blog.csdn.net/moreevan/article/details/11977115 Spring AOP 实现原理 2013-09-24 15:23 79554人阅读 评论(11) 收藏 举报  分类: spring(2)  版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)

Spring核心框架 - AOP的原理及源码解析

一.AOP的体系结构 如下图所示:(引自AOP联盟) 层次3语言和开发环境:基础是指待增加对象或者目标对象:切面通常包括对于基础的增加应用:配置是指AOP体系中提供的配置环境或者编织配置,通过该配置AOP将基础和切面结合起来,从而完成切面对目标对象的编织实现. 层次2面向方面系统:配置模型,逻辑配置和AOP模型是为上策的语言和开发环境提供支持的,主要功能是将需要增强的目标对象.切面和配置使用AOP的API转换.抽象.封装成面向方面中的逻辑模型. 层次1底层编织实现模块:主要是将面向方面系统抽象封

Spring之AOP原理_动态代理

面向方面编程(Aspect Oriented Programming,简称AOP)是一种声明式编程(Declarative Programming).声明式编程是和命令式编程(Imperative Programming)相对的概念.我们平时使用的编程语言,比如C++.Java.Ruby.Python等,都属命令式编程.命令式编程的意思是,程序员需要一步步写清楚程序需要如何做什么(How to do What).声明式编程的意思是,程序员不需要一步步告诉程序如何做,只需要告诉程序在哪些地方做什么

SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP

AOP(Aspect Oriented Programming).是面向切面编程的技术.AOP基于IoC基础.是对OOP的故意补充. AOP之所以能得到广泛应用,主要是由于它将应用系统拆分分了2个部分:核心业务逻辑(Core business concerns)及横向的通用逻辑,也就是所谓的切面Crosscutting enterprise concerns.比如,全部大中型应用都要涉及到的持久化管理(Persistent).事务管理(Transaction Management).权限管理(P

浅谈Spring(三)AOP原理

一.概念术语 AOP(Aspect Oriented Programming):面向切面编程. 面向切面编程(也叫面向方面编程),是目前软件开发中的一个热点,也是Spring框架中的一个重要内容.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率. 1. 切面(Aspect) 官方的抽象定义为"一个关注点的模块化,这个关注点可能会横切多个对象",在本例中,"切面"就是类TestAspect所关