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. STL源码剖析(仿函数/bind2nd)

    仿函数(functors)其实就是重载了operator()的对象. 下面简单先看看它的一个例子: #include <iostream> using namespace std; tem ...

  2. 【Datastage】在win10安装Datastge 8.7

    在win10安装提示Datastage提示如下错误: 强制安装: setup.exe -force 进入浏览器安装界面后 忽略"失败"即可成功安装.

  3. java文件读取与写入

    package com.myjava; import java.io.*; import java.util.ArrayList; import java.util.Collections; impo ...

  4. ubuntu14.04使用root用户登录桌面,ubuntu14.04root 转

    ubuntu安装好之后,默认是不能用root用户登录桌面的,只能使用普通用户或者访客登录.怎样开启root用户登录桌面呢? 先用普通用户登录,然后切换到root用户,然后执行如下命令: vi /usr ...

  5. Spring 框架的搭建及测试

    1.项目结构如下: 2.com.sxl.pojos==>Student.java package com.sxl.pojos; public class Student { private in ...

  6. Java成员变量与局部变量同名

    看到成员变量和局部变量同名这个知识点的时候一开始有点懵逼,想了一下其实特别简单. 先来看一个简单的代码. 首先我定义了一个Person类. public class Person { private ...

  7. 利用email.net设置网络代理发邮件

    近期在做一个项目,客户的内部网络须要设置代理才干收发邮件,本来一个简单的东西突然变得复杂了,在baidu搜索了非常久都没找到适合的组件.baidu就像个废物一样,没办法仅仅能去yahoo搜,结果在微软 ...

  8. web前端--移动端适配总结

    转自:https://segmentfault.com/a/1190000011586301 作者:Devinnn meta标签到底做了什么事情 做过移动端适配的小伙伴一定有遇到过这行代码: < ...

  9. Redis(三):windows下Redis的安装配置以及注意事项

    一.下载windows版本的Redis 去官网找了很久,发现原来在官网上可以下载的windows版本的,现在官网以及没有下载地址,只能在github上下载,官网只提供linux版本的下载 官网下载地址 ...

  10. Real-Time SQL Monitoring using DBMS_SQLTUNE

    Real-Time SQL Monitoring reports are available from three locations: Enterprise Manager - Click the ...