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. Lr_debug_message,Lr_output_message,Lr_error_message,Lrd_stmt,Lrd_fetch

    今天在群里,问了 Lr_debug_message,Lr_output_message,Lr_error_message,Lrd_stmt,Lrd_fetch.下 面我整理了下Lr_debug_mes ...

  2. 阿里云云盘扩容数据盘_Linux

    随着业务的增长,您的数据盘容量可能无法满足数据存储的需要,这时您可以使用 磁盘扩容 功能扩容数据盘.   说明 挂载在实例上的数据盘,只有当实例处于 运行中 (Running) 或 已停止(Stopp ...

  3. JBoss jar包冲突及jar加载顺序

    http://blog.163.com/javaee_chen/blog/static/17919507720116149511489/将一个完整的.war包部署到Jboss容器中,启动后报如下错误: ...

  4. mongodb - 集合重命名

    #创建新的集合yb > for(i=0;i<10;i++){db.yb.insert({'i':i})} WriteResult({ "nInserted" : 1 } ...

  5. php安全处理

    1.php.ini 修改 open_basedir='d:\wwwroot' //配置只能访问指定的网站目录 2.php.ini 修改 disable_funcitons=system,passthr ...

  6. List与String的相互转换

    List转字符串,用逗号隔开 List<string> list = new List<string>(); list.Add("a"); list.Add ...

  7. 多线程-ConcurrentHashMap(JDK1.8)

    前言 HashMap非线程安全的,HashTable是线程安全的,所有涉及到多线程操作的都加上了synchronized关键字来锁住整个table,这就意味着所有的线程都在竞争一把锁,在多线程的环境下 ...

  8. [容器]docker创建镜像

    手动创建: docker run -d -p mynginx:v2 nginx rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest- ...

  9. csu-1328 近似回文词 和 最长回文字符串

    原博文地址:http://blog.csdn.net/u012773338/article/details/39857997 最长回文子串 描述:输入一个字符串,求出其中最长的回文子串.子串的含义是: ...

  10. nyoj 460 项链 (区间dp)

    项链 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子, ...