面向切面编程(三)
来源:互联网 发布:php写入mysql数据库 编辑:程序博客网 时间:2024/05/23 21:59
本方法与面向切面编程(一)和(二)的实现结果是一样的,但是实现方法不一样。
再介绍一遍spring AOP中的专业术语(其中连接点、切入点、切面很重要):
1.通知(Advice):通知定义了切面是什么以及何时使用。描述了切面要完成的工作和何时需要执行这个工作。
2.连接点(Joinpoint):程序能够应用通知的一个“时机”,这些“时机”就是连接点,例如方法被调用时、异常被抛出时等等。
3.切入点(Pointcut):通知定义了切面要发生的“故事”和时间,那么切入点就定义了“故事”发生的地点,例如某个类或方法的名称,spring中允许我们方便的用正则表达式来指定
4.切面(Aspect):通知和切入点共同组成了切面:时间、地点和要发生的“故事”
5.引入(Introduction):引入允许我们向现有的类添加新的方法和属性(Spring提供了一个方法注入的功能)
6.目标(Target):即被通知的对象,如果没有AOP,那么它的逻辑将要交叉别的事务逻辑,有了AOP之后它可以只关注自己要做的事(AOP让他做爱做的事)
7.代理(proxy):应用通知的对象,详细内容参见设计模式里面的代理模式
8.织入(Weaving):把切面应用到目标对象来创建新的代理对象的过程,织入一般发生在如下几个时机:
(1)编译时:当一个类文件被编译时进行织入,这需要特殊的编译器才可以做的到,例如AspectJ的织入编译器(2)类加载时:使用特殊的ClassLoader在目标类被加载到程序之前增强类的字节代码(3)运行时:切面在运行的某个时刻被织入,SpringAOP就是以这种方式织入切面的,原理应该是使用了JDK的动态代理技术
示例代码:
BizImpl.java(实现类的接口):
/* * 时间:2016年9月28日20:41:10 * 程序功能:实现类的接口 * */ package com.sc.biz; public interface BizImpl { public void buy(String username,String bookname,double price); public void pinlun(String username,String pinlunleirong); }
BookBizImpl.java(实现类):
/* * 时间:2016年9月28日20:41:35 * 程序功能:实现类,继承接口并实现方法 * */ package com.sc.biz; public class BookBizImpl implements BizImpl { public void buy(String username, String bookname, double price) { System.out.println("用户名:"+username); System.out.println("书名:"+bookname); System.out.println("价格"+price); } public void pinlun(String username, String pinlunleirong) { System.out.println("评论人:"+username); System.out.println("评论类容:"+pinlunleirong); } }
DaiLiLei1.java(使用xml配置的代理类):
/* * 时间:2016年9月28日20:42:12 * 程序功能:代理类 * */ package com.sc.daililei; import java.util.Arrays; import java.util.Date; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; public class DaiLiLei1 { // 后置通知,jp.getSignature().getName()可以获取当前执行的方法名 // Arrays.toString(jp.getArgs())获取属性名 public void logBefore(JoinPoint jp) { System.out.println("[系统日志][" + new Date().toLocaleString() + "] 开始执行:" + jp.getSignature().getName() + "参数是:" + Arrays.toString(jp.getArgs())); } public void logAfter(JoinPoint jp) { System.out.println("[系统日志][" + new Date().toLocaleString() + "] 结束执行:" + jp.getSignature().getName() + "参数是:" + Arrays.toString(jp.getArgs())); } public void logAround(ProceedingJoinPoint jp) throws Throwable { System.out.println("[系统日志][" + new Date().toLocaleString() + "] 结束执行:" + jp.getSignature().getName() + "参数是:" + Arrays.toString(jp.getArgs())); Object obj = jp.proceed(); System.out.println("[系统日志][" + new Date().toLocaleString() + "] 结束执行:" + jp.getSignature().getName() + "参数是:" + Arrays.toString(jp.getArgs())); } }DaiLiLei.java(使用注解配置的代理类):
/* * 时间:2016年9月28日20:42:12 * 程序功能:代理类,使用注解方配置 * */ package com.sc.daililei; import java.util.Arrays; import java.util.Date; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; @Aspect public class DaiLiLei { // 该方法相当于在这个位置定义一个切点,以下方法都使用这个切点 @Pointcut("execution(* com.sc.biz.BookBizImpl .*(..))") public void heHe() { } // 后置通知,jp.getSignature().getName()可以获取当前执行的方法名 // Arrays.toString(jp.getArgs())获取属性名 @Before("heHe()") public void logBefore(JoinPoint jp) { System.out.println("[系统日志][" + new Date().toLocaleString() + "] 开始执行:" + jp.getSignature().getName() + "参数是:" + Arrays.toString(jp.getArgs())); } @After("heHe()") public void logAfter(JoinPoint jp) { System.out.println("[系统日志][" + new Date().toLocaleString() + "] 结束执行:" + jp.getSignature().getName() + "参数是:" + Arrays.toString(jp.getArgs())); } @Around("heHe()") public void logAround(ProceedingJoinPoint jp) throws Throwable { System.out.println("[系统日志][" + new Date().toLocaleString() + "] 结束执行:" + jp.getSignature().getName() + "参数是:" + Arrays.toString(jp.getArgs())); Object obj = jp.proceed(); //此处为前置通知和后置通知的分界点 System.out.println("[系统日志][" + new Date().toLocaleString() + "] 结束执行:" + jp.getSignature().getName() + "参数是:" + Arrays.toString(jp.getArgs())); } }
applicationContext.xml(Spring配置文件):
<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans ;http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/aop ;http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <!-- 使用xml配置 --> <!-- <bean id="bookBizImpl" class="com.sc.biz.BookBizImpl"></bean> <bean id="daiLiLei" class="com.sc.daililei.DaiLiLei1"></bean> <aop:config> <aop:aspect id="dai" ref="daiLiLei"> <aop:pointcut expression="execution(* com.sc.biz.BookBizImpl .*(..))" id="p"/> <aop:before method="logBefore" pointcut-ref="p"/> <aop:after method="logAfter" pointcut-ref="p"/> <aop:around method="logAround" pointcut-ref="p"/> </aop:aspect> </aop:config> --> <!-- 使用注解配置 --> <bean id="bookBizImpl" class="com.sc.biz.BookBizImpl"></bean> <bean id="daiLiLei" class="com.sc.daililei.DaiLiLei"></bean> <aop:aspectj-autoproxy></aop:aspectj-autoproxy></beans>
切面其实是一个普通的类,然后在配置文件中将它声明称切面
关于在配置文件中声明切面:
<aop:pointcut expression="execution(* com.sc.biz.BookBizImpl .*(..))" id="p"/>
expression里面的值设置方法:
1、任意公共方法的执行:
expression(public * *(..))
2、任意一个以set开始的方法的执行:
expression(* set* (..))
3、AccountService接口定义的任何方法的执行:
expression(* com.sc.service.AccountService.*(..))
4、在service包中定义的任何方法的执行:
expression(* com.sc.service.*.*(..))
5、在service包或其子包中定义的任一方法的执行:
expression(* com.sc.service..*.*(..))
expression(* com.sc.service..*.*(..))
在配置文件中使用切面:
例如:<aop:before method="logBefore" pointcut-ref="p"/>
声明通知:
常用:<aop:before/>
<aop:after/>
<aop:around/>
阅读全文
0 0
- 面向切面编程(三)
- AOP面向切面编程(三)
- 三、面向切面编程AOP
- Spring面向切面编程三
- 【spring框架】(三)面向切面编程(AOP)
- Spring学习笔记(三)--面向切面编程AoP
- Spring学习三(AOP面向切面编程)
- 面向切面编程AOP的浅显理解(三)
- Spring之面向切面编程AOP(三)
- 面向切面编程(转载)
- Aop(面向切面编程)
- 面向切面编程(AOP)
- AOP(面向切面编程)
- 面向切面编程(AOP)
- 面向切面编程(AOP)
- 面向切面编程(AOP)
- 面向切面编程(AOP)
- 面向切面编程(一)
- Android
- HTML/CSS学习记录(4)
- Ubuntu Docker 安装和使用
- Linux启动流程
- 测试远程主机的特定端口是否开通
- 面向切面编程(三)
- Asp.net Mvc3系列 之 Html.DropDownList
- springmvc注解开发之requestMapping
- C++学习:对象和类详细总结
- Matlab 编程基础(一)笔记
- java 验证包含属性的对象是否全部为空
- java.lang.NoSuchMethodError: org.springframework.beans.MutablePropertyValues.a
- 阿里云PHP-SMS短信服务——验证码发送教程
- 完美解决linux打包大于4G问题