Spring AOP(面向切面示例)
什么是AOP?
基本概念
切面(aspect):横切关注点被模块化的特殊对象。
通知(advice):切面必须要完成的工作。切面中的每个方向称之为通知。通知是在切面对象中的。
目标(target):被通知的对象。
代理(proxy):向目标对象应用通知后创建的对象。
连接点(joinpoint):目标对象的程序执行的某个特定位置。如某个方法调用前,调用后的位置。包括两个信息:1.目标程序的哪个方法?2.方法执行
前还是执行后?
切点(pointcut):每个类会有多个连接点,AOP通过切点定位到特定的边接点。
类比,连接点相当于数所成方圆 中的记录,而切点相当于查询条件。一个切点匹配多个连接点。
使用XML配置的方法:
1.导入 spring包和aspectj的两个jar包

2.目标对象(要切入的对象)
首先为了不违反开闭原则和更好的可扩展性,目标对象实际上是实现了已定义好的某个接口
接口:
package com.itnba.test;
public interface IHuman {
public void chifan();
public void shuijiao();
}
实现接口的两个类:
package com.itnba.test;
import org.springframework.stereotype.Component;
public class Chinese implements IHuman {
@Override
public void chifan() {
// TODO 自动生成的方法存根
System.out.println("中国人吃饭");
}
@Override
public void shuijiao() {
// TODO 自动生成的方法存根
System.out.println("中国人睡觉");
}
}
package com.itnba.test;
import org.springframework.stereotype.Component;
public class American implements IHuman {
@Override
public void chifan() {
// TODO 自动生成的方法存根
System.out.println("美国人吃饭");
}
@Override
public void shuijiao() {
// TODO 自动生成的方法存根
System.out.println("美国人睡觉");
}
}
3.定义一个切面类
package com.itnba.test; import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
public class Qiemian { public void chifanqian(){
System.out.println("洗手");
}
public void chifanhou(){
System.out.println("漱口");
}
public void shuijiaoqian(){
System.out.println("洗澡"); } }
4.XML文件配置
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"
default-autowire="byName"
>
<!-- 首相要实例化目标对象类和切面类 -->
<bean id="chinese" class="com.itnba.test.Chinese"></bean>
<bean id="american" class="com.itnba.test.American"></bean>
<bean id="qiemian" class="com.itnba.test.Qiemian"></bean> <aop:config>
<!-- 要切入的对象 -->
<aop:pointcut expression="execution(* com.itnba.test.*.chifan(..))" id="chifan"/>
<aop:pointcut expression="execution(* com.itnba.test.*.shijiao(..))" id="shijiao"/>
<!-- 切入点 -->
<aop:aspect id="ha" ref="qiemian"><!-- 切面类 -->
<!-- <aop:之前before、之后after... method="切面类中的方法" pointcut-ref="上面的切入的对象"/> -->
<aop:before method="chifanqian()" pointcut-ref="chifan"/><!-- 之前通知 -->
<aop:after method="chifanhou()()" pointcut-ref="chifan"/><!-- 之后通知 -->
<aop:before method="shuijiaoqian()" pointcut-ref="shijiao"/>
</aop:aspect>
</aop:config>
</beans>
5.运行
package com.itnba.test; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//要用接口接收
IHuman c= (IHuman)context.getBean("chinese");
c.chifan();
c.shuijiao();
System.out.println("*********************************");
//要用接口接收
IHuman a= (IHuman) context.getBean("american");
a.chifan();
a.shuijiao(); } }
结果:

使用注解的方法:
1.导如 spring包和aspectj的两个jar包

2.配置文件中加入aop命名空间
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd" > <!-- 自动扫描包下的类,并将其实例化。多个包之间用,隔开 -->
<context:component-scan base-package="com.itnba.test"></context:component-scan>
<!-- 配置文件中启动AspectJ的注解功能 ,默认是false,要将其改为true -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
</beans>
3.目标对象(要切入的对象)
首先为了不违反开闭原则和更好的可扩展性,目标对象实际上是实现了已定义好的某个接口
接口:
package com.itnba.test;
public interface IHuman {
public void chifan();
public void shuijiao();
}
实现接口的两个类:
package com.itnba.test; import org.springframework.stereotype.Component; @Component
public class Chinese implements IHuman { @Override
public void chifan() {
// TODO 自动生成的方法存根
System.out.println("中国人吃饭"); } @Override
public void shuijiao() {
// TODO 自动生成的方法存根
System.out.println("中国人睡觉");
} }
package com.itnba.test; import org.springframework.stereotype.Component; @Component
public class American implements IHuman { @Override
public void chifan() {
// TODO 自动生成的方法存根
System.out.println("美国人吃饭"); } @Override
public void shuijiao() {
// TODO 自动生成的方法存根
System.out.println("美国人睡觉");
} }
4.定义一个切面类,直接在里面注解
package com.itnba.test; import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect //声明该类是切面类
@Component//配置文件中启动自动扫描功能
public class Qiemian { @Before("execution(* com.itnba.test.*.chifan(..))")//在那个方法的之前通知 *代表全部..代表所有形参,不管有多少
public void chifanqian(){
System.out.println("洗手");
}
@After("execution(* com.itnba.test.*.chifan(..))")//在那个方法之后通知
public void chifanhou(){
System.out.println("漱口");
}
@Before("execution(* com.itnba.test.*.shuijiao(..))")
public void shuijiaoqian(){
System.out.println("洗澡"); } }
5.写好后用main函数来运行一下
package com.itnba.test; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Chinese c= context.getBean(Chinese.class);
c.chifan();
c.shuijiao();
System.out.println("*********************************");
American a= (American) context.getBean("american");
a.chifan();
a.shuijiao(); } }
结果:

这样,Spring的面向切面编程就简单介绍完了。
通知分类:
前置通知(@Before) -- 在目标方法执行前执行的通知。
后置通知(@After) -- 在目标方法执行后执行的通知。无论是否发生异常。后置通知中,无法读取目标方法返回的结果。
返回通知(@AfterReturnning) --在目标方法执行成功后执行的通知。在返回通知中可以访问目标返回结果的。
@AfterReturnning(value="execution(* com.itnba..*(..))",returning="result")
public void afterRun(Object result){
System.out.println(result);
}
异常通知(@AfterThrowing) -- 在目标方法执行出错后执行的通知。
@AfterThrowing(value="execution(* com.itnba..*(..))",throwing="ex")
public void afterThrowing(Exception ex){
System.out.println(ex.getMessage());
}
环绕通知(@Around) -- 需要切面方法携带ProceedingJoinPoion参数,类似于一个完整的动态代理,环绕通知必须要有一个返回值,是目标方法的返
回值。
@Around("execution(* com.itnba..*(..))")
public object aroundAdvice( ProceedingJoinPoint pjp){
object obj = null;
try{
//做前置通知
obj = pjp.proceed();
//做返回通知
}
catch(Exception ex){
//做异常通知
}
//做后置通知
return obj;
}
添加日志:
切面方法可以加入参数(JoinPoint) joinPost.getSignature().getXXX()获得相关方法信息
切面方法中可以加入Object参数,用来获得目标方法的返回值(只对返回通知起作用)
Spring AOP(面向切面示例)的更多相关文章
- 详细解读 Spring AOP 面向切面编程(二)
本文是<详细解读 Spring AOP 面向切面编程(一)>的续集. 在上篇中,我们从写死代码,到使用代理:从编程式 Spring AOP 到声明式 Spring AOP.一切都朝着简单实 ...
- 浅谈Spring AOP 面向切面编程 最通俗易懂的画图理解AOP、AOP通知执行顺序~
简介 我们都知道,Spring 框架作为后端主流框架之一,最有特点的三部分就是IOC控制反转.依赖注入.以及AOP切面.当然AOP作为一个Spring 的重要组成模块,当然IOC是不依赖于Spring ...
- 从源码入手,一文带你读懂Spring AOP面向切面编程
之前<零基础带你看Spring源码--IOC控制反转>详细讲了Spring容器的初始化和加载的原理,后面<你真的完全了解Java动态代理吗?看这篇就够了>介绍了下JDK的动态代 ...
- 详细解读 Spring AOP 面向切面编程(一)
又是一个周末, 今天我要和大家分享的是 AOP(Aspect-Oriented Programming)这个东西,名字与 OOP 仅差一个字母,其实它是对 OOP 编程方式的一种补充,并非是取而代之. ...
- spring AOP面向切面编程学习笔记
一.面向切面编程简介: 在调用某些类的方法时,要在方法执行前或后进行预处理或后处理:预处理或后处理的操作被封装在另一个类中.如图中,UserService类在执行addUser()或updateUse ...
- 【spring-boot】spring aop 面向切面编程初接触--切点表达式
众所周知,spring最核心的两个功能是aop和ioc,即面向切面,控制反转.这里我们探讨一下如何使用spring aop. 1.何为aop aop全称Aspect Oriented Programm ...
- 【spring-boot】spring aop 面向切面编程初接触
众所周知,spring最核心的两个功能是aop和ioc,即面向切面,控制反转.这里我们探讨一下如何使用spring aop. 1.何为aop aop全称Aspect Oriented Programm ...
- 【Spring系列】Spring AOP面向切面编程
前言 接上一篇文章,在上午中使用了切面做防重复控制,本文着重介绍切面AOP. 在开发中,有一些功能行为是通用的,比如.日志管理.安全和事务,它们有一个共同点就是分布于应用中的多处,这种功能被称为横切关 ...
- Spring AOP面向切面编程详解
前言 AOP即面向切面编程,是一种编程思想,OOP的延续.在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等等.在阅读本文前希望您已经对Spring有一定的了解 注:在能对代码进行添 ...
- Spring AOP 面向切面编程相关注解
Aspect Oriented Programming 面向切面编程 在Spring中使用这些面向切面相关的注解可以结合使用aspectJ,aspectJ是专门搞动态代理技术的,所以比较专业. ...
随机推荐
- Python游戏引擎开发(五):Sprite精灵类和鼠标事件
本次来实现Sprite类和鼠标事件. 说起这个Sprite啊,涉及过2D游戏研究领域的看官应该都听说过它. 它中文原意是"精灵",只是在不同人的眼中,它所表示的意义不同. 比方说在 ...
- Java加密技术(四)非对称加密算法RSA
RSA 这样的算法1978年就出现了.它是第一个既能用于数据加密也能用于数字签名的算法.它易于理解和操作.也非常流行.算法的名字以发明者的名字命名:Ron Rivest, AdiShamir ...
- windows下的Mysql安装与基本使用(zip)
一.安装过程 Mysql社区版下载地址:http://dev.mysql.com/downloads/mysql/ --注意,已管理员身份运行cmd.exe,很重要!!目录在,c:\windows\s ...
- R语言seq()函数用法
1.seq() 用来生成一组数字的函数. Usage: ## Default S3 method:seq(from = 1, to = 1, by = ((to - from)/(length.out ...
- PHP引用符&的用法详细解析
本文转自:http://blog.csdn.net/vip_linux/article/details/10206091PHP中引用符&的用法.关于php的引用(就是在变量或者函数.对象等前面 ...
- Python(调用函数、定义函数)
函数的返回值: return 值:只能返回一次,只要执行return函数就终止 返回值:没有类型限制,也没有个数限制 没有return:None 返回一个值 返回多个值:元组 先定义,后使用,定义阶段 ...
- 一个很牛的计算pi的c程序!
C语言是面向过程的一种高级程序设计语言,它在世界范围内使用很广泛,而且很流行.很多大型的应用软件,基本上是用C语言所编写的.在对操作系统以及系统使用程序.需要对硬件进行操作的场合,C语言较其他的高级语 ...
- 第二课 GCC入门之静态库以及共享库
序言: 前面一课讲了gcc的简单入门,包括gcc编译步骤:预处理:编译:汇编:链接.今天这节课就来讲下linux的库也欢迎大家吐糟共同学习. 原理: linux系统中分为2种库:静态库和共享库.静态库 ...
- Linux 搭建 SVN
一.yum 安装 subversion yum -y install subversion 二.创建svn版本库所在路径(建议放在opt.usr.home下) mkdir -p /usr/local/ ...
- Django学习笔记之Ajax入门
AJAX准备知识:JSON 什么是 JSON ? JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻量级的文本数据交换格式 JS ...