1、AOP概述

AOP技术即Aspect Oriented Programming的缩写,译为面向切面编程。AOP是OOP的一种延续,利用AOP技术可以对业务逻辑的各个部分进行隔离,从使得业务逻辑各部分之间的耦合性降低,提高程序的可重用性,同时提高了开发的效率。

AOP采用横向抽取机制,取代了传统纵向继承体系重复性代码,AOP可以在不修改源代码的前提下,对程序进行增强。

2、AOP技术的底层实现

  1. 基于jdk的动态代理:必须是面向接口的,只有实现了具体接口的类才能生成代理对象
  2. 基于CGLIB动态代理:对于没有实现接口的类,也可以产生代理,产生这个类的子类的方式

Spring的传统AOP中根据类是否实现接口而采用不同的代理方式,如果实现类接口,则使用jdk动态代理完成AOP,如果没有实现接口,采用CGLIB动态代理完成AOP。

JDK动态代理演示:

接口UserDao、实现类UserDaoImpl、动态代理类MyProxyUtils

 package com.alphajuns.demo1;

 public interface UserDao {

     public void save();

     public void update();

 }
 package com.alphajuns.demo1;

 public class UserDaoImpl implements UserDao {

     @Override
public void save() {
System.out.println("保存用户...");
} @Override
public void update() {
System.out.println("修改用户...");
} }
 package com.alphajuns.demo1;

 import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /*
* 使用JDK的方式生成动态代理
*/
public class MyProxyUtils { public static UserDao getProxy(final UserDao dao) {
// 使用Proxy类生成代理对象
UserDao proxy = (UserDao) Proxy.newProxyInstance(
dao.getClass().getClassLoader(),
dao.getClass().getInterfaces(),
new InvocationHandler() { @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("save".equals(method.getName())) {
System.out.println("记录日志...");
}
// 执行dao类中的方法
return method.invoke(dao, args);
}
}); // 返回代理对象
return proxy;
} }

CGLIB代理:

 package com.alphajuns.demo2;

 import java.lang.reflect.Method;

 import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy; public class MyCglibUtils { /*
* 使用Cglib方法生成代理对象
*/
public static BookDaoImpl getProxy() {
Enhancer enhancer = new Enhancer();
// 设置父类
enhancer.setSuperclass(BookDaoImpl.class);
// 设置回调函数
enhancer.setCallback(new MethodInterceptor() {
// 代理对象的方法执行,回调函数的方法就会执行
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if ("save".equals(method.getName())) {
System.out.println("记录日志...");
}
// 正常执行
return methodProxy.invokeSuper(obj, args);
}
}); // 生成代理对象
BookDaoImpl proxy = (BookDaoImpl) enhancer.create();
return proxy;
} }

3、AOP相关术语

  1. JoinPoint(连接点):被拦截的点。Spring中,这些点是指方法,Spring只支持方法类型的连接点。
  2. Pointcut(切入点):对需要被拦截的JoinPoint的定义。
  3. Advice(通知/增强):拦截到JointPoint之后所要做的事情就是通知。通知分为前置通知、后置通知、异常通知、最终通知、环绕通知
  4. Introduction(引介):引介是一种特殊的通知,在不修改代码的前提下,Introduction可以在运行期为类动态地添加一些方法或field
  5. Target(目标对象):代理的目标对象
  6. Weaving(织入):是指增强应用到目标对象来创建新的代理对象的过程
  7. Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类
  8. Aspect(切面):切入点与通知的结合

4、XML方式AOP开发步骤

  1. 创建WEB项目,引入jar包
  2. 创建Spring配置文件,引入AOP的schema约束
  3. 创建包结构,编写具体的接口和实现类
  4. 将目标类配置到Spring配置文件中
  5. 定义切面类
  6. 在配置文件中定义切面类
  7. 在配置文件中完成AOP配置
  8. 测试

5、切入点表达式

切入点表达式在下面applicationContext2中以注释形式进行了介绍。

6、AOP通知类型

  1. 前置通知:在目标类的方法执行之前执行
  2. 后置通知:在目标类方法执行之后执行
  3. 异常抛出通知:在抛出异常后通知
  4. 环绕通知:方法执行前后都执行

7、AOP应用举例

接口CustomerDao、实现类CustomerDaoImpl、切面类MyAspectXml、Spring配置文件applicationContext、applicationContext2、applicationContext3

 package com.alphajuns.demo3;

 public interface CustomerDao {

     public void save();

     public void update();

 }
 package com.alphajuns.demo3;

 public class CustomerDaoImpl implements CustomerDao {

     @Override
public void save() {
System.out.println("保存客户...");
} @Override
public void update() {
System.out.println("更新客户...");
} }
 package com.alphajuns.demo3;

 import org.aspectj.lang.ProceedingJoinPoint;

 /*
* 切面类:切入点+通知
*/
public class MyAspectXml { /*
* 通知(具体的增强)
*/
public void log() {
System.out.println("记录日志...");
} /*
* 最终通知:方法执行成功或出现异常,都会执行
*/
public void after() {
System.out.println("最终通知...");
} /*
* 后置通知:方法执行之后,执行后置通知,出现异常则不执行
*/
public void afterReturn() {
System.out.println("后置通知...");
} /*
* 环绕通知:方法执行之前和方法执行之后进行通知,默认情况下,目标对象的方法不执行。需要手动让目标对象的方法执行
*/
public void around(ProceedingJoinPoint joinPoint) {
System.out.println("环绕通知1...");
try {
// 手动让目标对象的方法执行
joinPoint.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("环绕通知2...");
} }
 <?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" 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"> <!-- bean definitions here --> <!-- 配置客户的dao -->
<bean id="customerDao" class="com.alphajuns.demo3.CustomerDaoImpl"/>
<!-- 配置切面类 -->
<bean id="myAspectXml" class="com.alphajuns.demo3.MyAspectXml"/>
<!-- 配置AOP -->
<aop:config>
<!-- 配置切面类:切入点+通知类型 -->
<aop:aspect ref="myAspectXml">
<!-- 配置前置通知 -->
<aop:before method="log" pointcut="execution(public void com.alphajuns.demo3.CustomerDaoImpl.save())"/>
</aop:aspect>
</aop:config> </beans>
 <?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" 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"> <!-- bean definitions here --> <!-- 配置客户的dao -->
<bean id="customerDao" class="com.alphajuns.demo3.CustomerDaoImpl"/>
<!-- 配置切面类 -->
<bean id="myAspectXml" class="com.alphajuns.demo3.MyAspectXml"/>
<!-- 配置AOP -->
<aop:config>
<!-- 配置切面类:切入点+通知类型 -->
<aop:aspect ref="myAspectXml">
<!-- 配置前置通知 -->
<!-- 切入点的表达式
1、execution() 固定的,不能不写
2、public 可以省略不写
3、void出可以用*替代,表示返回值类型任意,不能省略不写
4、包的简写方式
5、类的写法
6、方法的写法
7、方法的参数
-->
<!-- 完整写法 -->
<!-- <aop:before method="log" pointcut="execution(public void com.alphajuns.demo3.CustomerDaoImpl.save())"/> -->
<!-- public可以省略不写 -->
<!-- <aop:before method="log" pointcut="execution(void com.alphajuns.demo3.CustomerDaoImpl.save())"/> -->
<!-- void出用*替代 -->
<!-- <aop:before method="log" pointcut="execution(* com.alphajuns.demo3.CustomerDaoImpl.save())"/> -->
<!-- 包的写法 -->
<!-- <aop:before method="log" pointcut="execution(* com.alphajuns.demo3.CustomerDaoImpl.save())"/> -->
<!-- 包的写法 -->
<!-- <aop:before method="log" pointcut="execution(* *..*.CustomerDaoImpl.save())"/> -->
<!-- 类的写法 -->
<!-- <aop:before method="log" pointcut="execution(* com.alphajuns.demo3.*DaoImpl.save())"/> -->
<!-- 方法写法 -->
<!-- <aop:before method="log" pointcut="execution(* com.alphajuns.demo3.CustomerDaoImpl.*save())"/> -->
<!-- 方法的参数 -->
<aop:before method="log" pointcut="execution(* com.alphajuns.demo3.CustomerDaoImpl.*save(..))"/>
</aop:aspect>
</aop:config> </beans>
 <?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" 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"> <!-- bean definitions here --> <!-- 配置客户的dao -->
<bean id="customerDao" class="com.alphajuns.demo3.CustomerDaoImpl"/>
<!-- 配置切面类 -->
<bean id="myAspectXml" class="com.alphajuns.demo3.MyAspectXml"/>
<!-- 配置AOP -->
<aop:config>
<!-- 配置切面类:切入点+通知类型 -->
<aop:aspect ref="myAspectXml">
<!-- 配置前置通知 -->
<!-- <aop:before method="log" pointcut="execution(public void com.alphajuns.demo3.CustomerDaoImpl.save())"/> -->
<!-- 配置后置通知 -->
<!-- <aop:after method="log" pointcut="execution(public void com.alphajuns.demo3.CustomerDaoImpl.save())"/> -->
<!-- 环绕通知 -->
<aop:around method="around" pointcut="execution(public void com.alphajuns.demo3.CustomerDaoImpl.save())"/>
</aop:aspect>
</aop:config> </beans>

Spring框架中的AOP技术----配置文件方式的更多相关文章

  1. Spring框架中的AOP技术----注解方式

    利用AOP技术注解的方式对功能进行增强 CustomerDao接口 package com.alphajuns.demo1; public interface CustomerDao { public ...

  2. spring框架中的aop技术

    1. 什么是AOP, 面向切面编程 AOP为Aspect Oriented Programming的缩写, 意为:面向切面编程,主要是使各部分之间的耦合度降低, 提高程序的可重用性, 同时提高了开发的 ...

  3. 3.Spring框架中的标签与配置文件分离

    1.Spring框架中标签的配置 1. id属性和name属性的区别 * id -- Bean起个名字,在约束中采用ID的约束,唯一 * 取值要求:必须以字母开始,可以使用字母.数字.连字符.下划线. ...

  4. Spring框架中的aop操作之二 通过配置文件实现增强

    aop表达式写法 配置文件代码: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=&q ...

  5. Spring框架的Bean管理的配置文件方式

    1. id属性和name属性的区别 * id -- Bean起个名字,在约束中采用ID的约束,唯一 * 取值要求:必须以字母开始,可以使用字母.数字.连字符.下划线.句话.冒号 id:不能出现特殊字符 ...

  6. Spring框架中的aop操作之一 及aspectjweaver.jar与aopalliance-1.0.jar下载地址 包含beans 注解context 和aop的约束

    (aspect oriented programming面向切面编程) 首先在原有的jar包: 需Spring压缩包中的四个核心JAR包 beans .context.core 和expression ...

  7. Spring Security框架中踢人下线技术探索

    1.背景 在某次项目的开发中,使用到了Spring Security权限框架进行后端权限开发的权限校验,底层集成Spring Session组件,非常方便的集成Redis进行分布式Session的会话 ...

  8. Spring框架的JDBC模板技术和事物

    Spring框架的JDBC模板技术         技术分析之Spring框架的JDBC模板技术概述  1. Spring框架中提供了很多持久层的模板类来简化编程,使用模板类编写程序会变的简单     ...

  9. Spring框架IOC和AOP介绍

    说明:本文部分内容参考其他优秀博客后结合自己实战例子改编如下 Spring框架是个轻量级的Java EE框架.所谓轻量级,是指不依赖于容器就能运行的.Struts.Hibernate也是轻量级的. 轻 ...

随机推荐

  1. 一学就会之ado.net(一)

    ado.net十一组用于和数据源进行交互的面向对象类库.数据源能够是数据库也能够是文本文件.excel表格或者XML文件. 简单来说.ado.net就是与不同的数据源进行交互(增删改查)的. ado. ...

  2. vfork & fork

    转载 http://coolshell.cn/articles/12103.html 在知乎上,有个人问了这样的一个问题——为什么vfork的子进程里用return,整个程序会挂掉,而且exit()不 ...

  3. 我的Go语言学习之旅二:入门初体验 Hello World

    好吧,全部的程序猿们都已经习惯了.学习不论什么一门语言,我们都会以Hello World实例開始我们的学习,我也不例外.先来一个简单的样例 打开编辑器 (能够用记事本,我已经习惯 Notepad++了 ...

  4. 准备你的Adempiere开发环境(1)- 编译

    1. 安装JDK 1.6. 2. 安装Eclipse IDE for Java EE Developers. 3. 导入adempire-360lts: 4. 关闭adempiere-360lts的B ...

  5. Docker构建nginx的nginx-rtmp-module视频服务器镜像

    文章地址:https://www.cnblogs.com/linyilong3/p/5862595.html GitHub nginx-rtmp-module 及配置 Dockerfile构建配置: ...

  6. 删除MYSQL账号多于的空用户

    默认情况下,mysql安装好之后,会存在匿名用户,也可以叫空用户,输入mysql之后直接回车便可进入mysql. 该匿名用户具有一定的权限,通过SHOW DATABASES;可以查看到informat ...

  7. IIS6.0应用程序池回收(转载)

    这段时间公司的程序经常出现问题,然后整个应用程序就不能访问了,我们的服务器版本:window 2003 SP1,IIS6.0,没有安装Microsoft Visual Studio .NET . 问题 ...

  8. ubuntu:好用的help命令

    以前光知道如何不清楚某个命令的用法可以打上后缀 ‘ --help' 现在刚发现,原来还有help命令来帮忙,如果你安装的是中文支持,在ubuntu上, 那么部分命令说明还是中文版哦. 举例: help ...

  9. webpack相关资料

    百度webpackhttps://www.zhihu.com/question/39290543http://xingdongpeng.com/2016/08/15/webpack-%E6%80%BB ...

  10. 解决 Netbeans Ant: taskdef class org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs cannot be found

    你在用Netbeans(实际上是Ant)Clean and Build你的项目生成可执行文件(例如Windows下的exe文件)时候遇到报错 或者遇到这样的报错: The libs.CopyLibs. ...