Spring切面编程步骤
| 什么是面向切面编程 |
面向对象的编程主要注重核心业务,而面向切面编程主要关注一些不是核心的业务,但又是必须的辅助功能,比如一个完整的系统中,记录平时系统运行时抛出的异常,需要我们去记录,以便我们对系统尽快的修复。这就是我们常用的日志。如果对一些要求比较重要的数据操作,事务是不可少的,如金融系统,这样的数据很重要,每步操作都很重要,我们就应该用到事务处理。这就是我们常用的事务处理。可根据你的系统数据的重要性,有选择的应用。还用一个常用的就是安全验证了,它也是常用的,对于不同的页面,访问的身份也不一样。这就是我们常用的身份验证。以上这些不是针对特定那个业务模块的,可能针对所有的模块。它们只是一些附加的功能,相对模块的主功能而言。如果在每个模块中都夹杂着这些不是核心业务的代码,看起来与核心业务有点关系,但这样处理,会对以后的维护比较头疼。同时也违背了面向对象的一条原则,自己对自己负责。本不属于这个方法的业务也放在了其中。这样的代码不仅难维护,重用性也不好,耦合度也比较大。内聚性也比较低。这样的代码眼前可能不会有什么麻烦,但给后期的维护人员带来了麻烦。
面向方面的编程主要是辅助核心业务的,它并不是核心业务,但它又是不可缺少的。我们可以这样理解它与面向对象思想的联合使用。其实面向方面编程就是把那些夹杂在核心业务方法里面的代码抽取出来并模块化,把它们单独看成一个模块功能.来与核心业务共同完成比较完善的功能.
面向方面编程( Aspect-Oriented Programming,AOP)很早就出现了,它与spring的Ioc结合使用,更加体现了aop的强大功能所在.在讲它与spring结合使用之前先说几个难听,难懂的概念.它为什么不命名一些容易理解的概念了,因为aop很早就有人对它们命名了, 所以spring中讲的aop也不例外.在jboss,AspectJ…中都有aop这个概念.概念都一样的
原文地址:参考文章
| AOP中的基本概念 |
aspect(切面)
实现了cross-cutting功能,是针对切面的模块。最常见的是logging模块,这样,程序按功能被分为好几层,如果按传统的继承的话,商业模型继承日志模块的话根本没有什么意义,而通过创建一个logging切面就可以使用AOP来实现相同的功能了。
jointpoint(连接点
连接点是切面插入应用程序的地方,该点能被方法调用,而且也会被抛出意外。连接点是应用程序提供给切面插入的地方,可以添加新的方法。比如以上我们的切点可以认为是findInfo(String)方法。
advice(处理逻辑)
advice是我们切面功能的实现,它通知程序新的行为。如在logging里,logging advice包括logging的实现代码,比如像写日志到一个文件中。advice在jointpoint处插入到应用程序中。以上我们在MyHandler.java中实现了advice的功能
pointcut(切点)
pointcut可以控制你把哪些advice应用于jointpoint上去,通常你使用pointcuts通过正则表达式来把明显的名字和模式进行匹配应用。决定了那个jointpoint会获得通知。
introduction
允许添加新的方法和属性到类中。
target(目标类)
是指那些将使用advice的类,一般是指独立的那些商务模型。比如以上的StudentInfoServiceImpl.
proxy(代理类)
使用了proxy的模式。是指应用了advice的对象,看起来和target对象很相似。
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切面编程步骤的更多相关文章
- Spring切面编程实践【原创】
定义 什么叫Spring面向切面编程(AOP),请自行百度,这边就不做详细介绍了. 场景 有两个对象,字典和工程信息Bean,每次新增或修改对象时,记录新增和修改的时间. 基类定义 package m ...
- spring切面编程AOP 范例一
参照网上的spring AOP编程实例进行配置,但是碰到了几个坑.这篇文章重点讲解一下我踩过的两个坑: 1.使用@Service自动装配的时候,基础扫描包配置要正确: 2.xml中切面配置中的exec ...
- spring aop使用,spring aop注解,Spring切面编程
================================ ©Copyright 蕃薯耀 2020-01-21 https://www.cnblogs.com/fanshuyao/ 一.第一步, ...
- spring切面编程
xml配置实现 先写三个类 public String amethod(String s) { System.out.println("This is AAAAAAAAAAAAAAAA&q ...
- Spring切面编程AOP
- Spring切面编程Aspect之@Before和@Around用法
查看dao层使用的sql import java.util.Arrays; import org.apache.commons.lang.ArrayUtils; import org.aspectj. ...
- spring aop 切面编程中获取具体方法的方法
spring 切面编程中获取具体方法的方法 工作中,使用环绕通知,用来捕获异常,然后通过获取方法的返回值,返回不同的数据给到调用方. 由于方法的返回值不同,我们处理异常时,也需要返回不同的格式. 这时 ...
- Spring中AOP简介与切面编程的使用
Spring中AOP简介与使用 什么是AOP? Aspect Oriented Programming(AOP),多译作 "面向切面编程",也就是说,对一段程序,从侧面插入,进行操 ...
- Spring之注解实现aop(面向切面编程)
1:Aop(aspect object programming)面向切面编程,名词解释: 1.1:功能:让关注点代码与业务逻辑代码分离 1.2:关注点 重复代码就叫做关注点 ...
随机推荐
- XJOI1564最小距离问题
最小距离问题 我国蒙古大草原上有N(N是不大于100的自然数)个牧民定居点P1(X1,Y1).P2(X2,Y2). -Pn(Xn,Yn),相应地有关权重为Wi,现在要求你在大草原上找一点P(Xp,Yp ...
- 手机自动化测试:搭建appium手机自动化测试开发环境
手机自动化测试:搭建appium手机自动化测试开发环境 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大 ...
- android.util.Log常用方法
android.util.Log常用的方法有以下5个: Log.v() Log.d() Log.i() Log.w() 以及 Log.e() .根据首字母分别对应VERBOSE,DEBUG,INFO, ...
- 改变iOS app的icon(iOS10.3)
改变iOS app的icon 官方 iOS10.3新增了可以让开发者去更改app的icon,接下来看看怎么更改. 官方API给的东西很少,只是介绍了一个实例方法: open func setAlter ...
- "!function",自执行函数表达式
如题为自执行函数表达式.在这种情况下,解析器在解析function关键字的时候,会将相应的代码解析成function表达式,而不是function声明.下面2个括弧()都会立即执行 (function ...
- Java 9 尝鲜之JShell交互式编程环境
JShell--Java 9 的交互式编程环境 本文要求读者有基本的 Java 知识. Tips Java 9 的代码由于提供了新特性,所以有些代码并不支持向后兼容.也就是说,用 Java 9 写的代 ...
- position relative
position的默认值是static,(也就是说对于任意一个元素,如果没有定义它的position属性,那么它的position:static) 如果你想让这个#demo里的一个div#sub相对于 ...
- Named function expressions demystified
Introduction Surprisingly, a topic of named function expressions doesn't seem to be covered well eno ...
- git的使用及常用命令(二)
一,把文件放在版本库中 执行 git add XXX文件名 在执行 git commit -m ‘提交注释' 查看状态 git status 如果没有改变文件,nothing to comment ...
- 树莓派的GPIO编程
作者:Vamei 出处:http://www.cnblogs.com/vamei 严禁转载. 树莓派除了提供常见的网口和USB接口 ,还提供了一组GPIO(General Purpose Input/ ...