什么是面向切面编程

面向对象的编程主要注重核心业务,而面向切面编程主要关注一些不是核心的业务,但又是必须的辅助功能,比如一个完整的系统中,记录平时系统运行时抛出的异常,需要我们去记录,以便我们对系统尽快的修复。这就是我们常用的日志。如果对一些要求比较重要的数据操作,事务是不可少的,如金融系统,这样的数据很重要,每步操作都很重要,我们就应该用到事务处理。这就是我们常用的事务处理。可根据你的系统数据的重要性,有选择的应用。还用一个常用的就是安全验证了,它也是常用的,对于不同的页面,访问的身份也不一样。这就是我们常用的身份验证。以上这些不是针对特定那个业务模块的,可能针对所有的模块。它们只是一些附加的功能,相对模块的主功能而言。如果在每个模块中都夹杂着这些不是核心业务的代码,看起来与核心业务有点关系,但这样处理,会对以后的维护比较头疼。同时也违背了面向对象的一条原则,自己对自己负责。本不属于这个方法的业务也放在了其中。这样的代码不仅难维护,重用性也不好,耦合度也比较大。内聚性也比较低。这样的代码眼前可能不会有什么麻烦,但给后期的维护人员带来了麻烦。

面向方面的编程主要是辅助核心业务的,它并不是核心业务,但它又是不可缺少的。我们可以这样理解它与面向对象思想的联合使用。其实面向方面编程就是把那些夹杂在核心业务方法里面的代码抽取出来并模块化,把它们单独看成一个模块功能.来与核心业务共同完成比较完善的功能.

面向方面编程( Aspect-Oriented Programming,AOP)很早就出现了,它与spring的Ioc结合使用,更加体现了aop的强大功能所在.在讲它与spring结合使用之前先说几个难听,难懂的概念.它为什么不命名一些容易理解的概念了,因为aop很早就有人对它们命名了, 所以spring中讲的aop也不例外.在jboss,AspectJ…中都有aop这个概念.概念都一样的

原文地址:参考文章

AOP中的基本概念

  1. aspect(切面)

    实现了cross-cutting功能,是针对切面的模块。最常见的是logging模块,这样,程序按功能被分为好几层,如果按传统的继承的话,商业模型继承日志模块的话根本没有什么意义,而通过创建一个logging切面就可以使用AOP来实现相同的功能了。

  2. jointpoint(连接点

    连接点是切面插入应用程序的地方,该点能被方法调用,而且也会被抛出意外。连接点是应用程序提供给切面插入的地方,可以添加新的方法。比如以上我们的切点可以认为是findInfo(String)方法。

  3. advice(处理逻辑)

    advice是我们切面功能的实现,它通知程序新的行为。如在logging里,logging advice包括logging的实现代码,比如像写日志到一个文件中。advice在jointpoint处插入到应用程序中。以上我们在MyHandler.java中实现了advice的功能

  4. pointcut(切点)

    pointcut可以控制你把哪些advice应用于jointpoint上去,通常你使用pointcuts通过正则表达式来把明显的名字和模式进行匹配应用。决定了那个jointpoint会获得通知。

  5. introduction

    允许添加新的方法和属性到类中。

  6. target(目标类)

    是指那些将使用advice的类,一般是指独立的那些商务模型。比如以上的StudentInfoServiceImpl.

  7. proxy(代理类)

    使用了proxy的模式。是指应用了advice的对象,看起来和target对象很相似。

  8. weaving(插入)

    是指应用aspects到一个target对象创建proxy对象的过程:complie time,classload time,runtime

IDE

IDE使用IDEA2016.1.2

关于开发步骤部分,请查看本文的Spring的配置文件部分,已经给出充分的注释。

项目管理采用Maven,用到的依赖见下面的pom文件内容。

<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <parent>
<groupId>com.springinaction</groupId>
<artifactId>example-code</artifactId>
<version>3.0.0</version>
</parent> <modelVersion>4.0.0</modelVersion>
<groupId>com.springinaction</groupId>
<artifactId>springidol-aop</artifactId>
<version>3.0.0</version>
<packaging>jar</packaging> <name>Spring in Action Spring Idol - AOP</name>
<url>http://www.manning.com/walls4</url> <dependencies>
<dependency>
<groupId>${spring.group}</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>${spring.group}</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>${spring.group}</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.6</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

相关bean的编写,本文用到的bean如下

`Instrument`
package com.springinaction.springidol;
public interface Instrument {
public void play();
}
`Instrumentalist`
package com.springinaction.springidol;

public class Instrumentalist implements Performer {
public void perform() throws PerformanceException {
instrument.play();
} private Instrument instrument; public void setInstrument(Instrument instrument) {
this.instrument = instrument;
} public Instrument getInstrument() {
return instrument;
}
}
Performer
package com.springinaction.springidol;

public interface Performer {
void perform() throws PerformanceException;
}
PerformanceException
package com.springinaction.springidol;

public class PerformanceException extends Exception {
private static final long serialVersionUID = 1L; }
Guitar
package com.springinaction.springidol;

public class Guitar implements Instrument {
public void play() {
System.out.println("Strum strum strum");
}
}
Audience
package com.springinaction.springidol;

public class Audience {
public void takeSeats() { //<co id="co_takeSeats"/>
System.out.println("The audience is taking their seats.");
} public void turnOffCellPhones() { //<co id="co_turnOffCellPhones"/>
System.out.println("The audience is turning off their cellphones");
} public void applaud() { //<co id="co_applaud"/>
System.out.println("CLAP CLAP CLAP CLAP CLAP");
} public void demandRefund() { //<co id="co_demandRefund"/>
System.out.println("Boo! We want our money back!");
}
}

Spring的配置

<?xml version="1.0" encoding="UTF-8"?>
<!--1.确定需要引入哪些明明空间-->
<!--1.1 Spring beans-->
<!--1.2 Spring Context-->
<!--1.3 Spring aop-->
<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">
<!--2.创建一个乐师对象-->
<!--2.1我们假设名称为frank-->
<bean id="frank" class="com.springinaction.springidol.Instrumentalist">
<!--2.2指定该乐师能够演奏的乐器,这是代码里面约定的-->
<property name="instrument">
<!--2.3这里采用内部bean的方式为其注入属性-->
<bean class="com.springinaction.springidol.Guitar"></bean>
</property>
</bean> <!--3.注册切面方法所在类-->
<bean id="audience" class="com.springinaction.springidol.Audience"></bean> <!--4.配置切面-->
<!--4.1声明配置的根节点-->
<aop:config>
<!--4.2创建或者说是声明切面-->
<aop:aspect ref="audience">
<!--4.3使用aop:before1-->
<aop:before method="takeSeats"
pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"></aop:before>
<!--4.4使用aop:before2-->
<aop:after-returning method="turnOffCellPhones"
pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"></aop:after-returning>
<!--4.5使用aop:after-returning-->
<aop:after-returning method="applaud"
pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"></aop:after-returning>
<!--4.6使用aop:after-throwing-->
<aop:after-throwing method="demandRefund"
pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"></aop:after-throwing>
</aop:aspect>
</aop:config>
<!--开始测试吧-->
</beans>

junit测试类的内容

package com.springinaction.springidol;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /**
* Created by Administrator on 2016/5/28.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:com/springinaction/springidol/spring-idol-myxml.xml"})
public class MyTest {
@Autowired
ApplicationContext context;
/**
* 测试切面及切点是否工作
*/
@Test
public void testAspect() throws PerformanceException {
Performer frank = (Performer) context.getBean("frank");
frank.perform();
}
}

junit的运行结果

Spring切面编程步骤的更多相关文章

  1. Spring切面编程实践【原创】

    定义 什么叫Spring面向切面编程(AOP),请自行百度,这边就不做详细介绍了. 场景 有两个对象,字典和工程信息Bean,每次新增或修改对象时,记录新增和修改的时间. 基类定义 package m ...

  2. spring切面编程AOP 范例一

    参照网上的spring AOP编程实例进行配置,但是碰到了几个坑.这篇文章重点讲解一下我踩过的两个坑: 1.使用@Service自动装配的时候,基础扫描包配置要正确: 2.xml中切面配置中的exec ...

  3. spring aop使用,spring aop注解,Spring切面编程

    ================================ ©Copyright 蕃薯耀 2020-01-21 https://www.cnblogs.com/fanshuyao/ 一.第一步, ...

  4. spring切面编程

    xml配置实现 先写三个类 public String amethod(String s) {  System.out.println("This is AAAAAAAAAAAAAAAA&q ...

  5. Spring切面编程AOP

  6. Spring切面编程Aspect之@Before和@Around用法

    查看dao层使用的sql import java.util.Arrays; import org.apache.commons.lang.ArrayUtils; import org.aspectj. ...

  7. spring aop 切面编程中获取具体方法的方法

    spring 切面编程中获取具体方法的方法 工作中,使用环绕通知,用来捕获异常,然后通过获取方法的返回值,返回不同的数据给到调用方. 由于方法的返回值不同,我们处理异常时,也需要返回不同的格式. 这时 ...

  8. Spring中AOP简介与切面编程的使用

    Spring中AOP简介与使用 什么是AOP? Aspect Oriented Programming(AOP),多译作 "面向切面编程",也就是说,对一段程序,从侧面插入,进行操 ...

  9. Spring之注解实现aop(面向切面编程)

    1:Aop(aspect object programming)面向切面编程,名词解释:    1.1:功能:让关注点代码与业务逻辑代码分离    1.2:关注点        重复代码就叫做关注点  ...

随机推荐

  1. 踩坑实录 使用 cardview 时报错 error: No resource identifier found for attribute 'cardCornerRadius' in package 'com.xxxxx.xxx'

    在项目中引用 cardview 卡片布局,编译时 Android Studio 报出下面图片中红框标记的错误: 出现这种情况的原因在于没有导入 cardview 卡片布局相应的依赖包,因此我们需要在 ...

  2. PHP获得文件创建、修改、访问时间 filectime() filemtime() fileatime()

    转载博客 零度_PHP的博客   http://blog.sina.com.cn/s/blog_8edc37a801016hk1.html PHP获得文件创建.修改.访问时间 PHP filectim ...

  3. 【Electron】Electron开发入门(五):项目打包

    一.安装 electron-packager PS:安装之前,先复制一份package.json文件到./app目录下,然后改下./app目录下package.json里 "main&quo ...

  4. 老李推荐:第14章8节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-获取控件列表并建立控件树 5

    看这段代码之前还是请回到“图13-6-1 NotesList控件列表”中重温一下一个控件的每个属性名和值是怎么组织起来的: android.widget.FrameLayout@41901ab0 dr ...

  5. $_GET

    POST GET ,是提交表单的两种方式,GET传值就用$_GET获取,POST提交表单就用$_POSTpost与get的区别是一个在地址栏显示参数,另一个不显示 如果地址是这样:http://zhi ...

  6. kafka各个版本特性预览介绍

    kafka-0.8.2 新特性 producer不再区分同步(sync)和异步方式(async),所有的请求以异步方式发送,这样提升了客户端效率.producer请求会返回一个应答对象,包括偏移量或者 ...

  7. sql中 datediff的使用

    简介:我们在sql中经常要判断年或者月或者日是否相等,我们可以用datediff函数,使用很方便 datediff:判断年或月或日或周.星期.小时.分钟等的差别数使用格式: DATEDIFF(date ...

  8. nginx学习笔记——http module分析

         源码:nginx 1.12.0           nginx由于其高性能.扩充性好等特点在迅速走红,越来越多的公司采用nginx作web服务器.负载均衡.waf等 工作,一些基于nginx ...

  9. Apache日志分割

    1.cronolog安装 采用 cronolog 工具进行 apache 日志分割 http://download.chinaunix.net/download.php?id=3457&Res ...

  10. 主机ping通虚拟机,虚拟机ping通主机解决方法(NAT模式)

    有时候需要用虚拟机和宿主机模拟做数据交互,ping不通是件很烦人的事,本文以net模式解决这一问题. 宿主机系统:window7 虚拟机系统:CentOs7 连接方式:NAT模式 主机ping通虚拟机 ...