AOP实例(通过Proxy代理模式)

Spring AOP使用纯java实现,不需要专门的编译过程和类装载器,它在运行期间通过代理方式向目标类织入增强代码,它更侧重于提供一种和Spring IoC容器整合的AOP实现,在Spring中,我们可以无缝的将AOP,IoC,AspectJ整合在一起。

Spring AOP使用了两种代理机制:一种是基于JDK的动态代理,一种是基于CGLib的动态代理;

JDK1.3以后,java提供了动态代理技术,允许开发者在运行期间动态的创建接口的代理实例,JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler,其中InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态的将横切逻辑和业务逻辑编织在一起。

下面我们来看一个JDK动态代理的例子:

1.业务接口UserService.java

package spring.aop.demo1;

public interface UserService {
void removeUser(int userId);
}

2.横切逻辑代理监视代码PerformanceMonitor.java

package spring.aop.demo1;

public class MethodPerformance {

    private long begin;

    private long end;

    private String serviceMethod;

    public MethodPerformance(String serviceMethod) {
this.serviceMethod = serviceMethod;
this.begin = System.currentTimeMillis();
} public void printPerformance() {
this.end = System.currentTimeMillis();
long elapse = end - begin; System.out.println(serviceMethod + "花费" + elapse + "毫秒");
} }
package spring.aop.demo1;

public class PerformanceMonitor {

    // 通过一个ThreadLocal保存调用线程相关的性能监视信息
private static ThreadLocal<MethodPerformance> performanceRecord = new ThreadLocal<MethodPerformance>(); // 启动对一目标方法的性能监视
public static void begin(String method) {
System.out.println("begin monitor...");
MethodPerformance mp = new MethodPerformance(method);
performanceRecord.set(mp);
} public static void end() {
System.out.println("end monitor...");
MethodPerformance mp = performanceRecord.get();
mp.printPerformance();
} }

3.横切逻辑代理代码PerformanceHandler.java

package spring.aop.demo1;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; public class PerformanceHandler implements InvocationHandler { private Object target; public PerformanceHandler(Object target) {
this.target = target;
} @Override
public Object invoke(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
PerformanceMonitor.begin(target.getClass().getName() + "."
+ arg1.getName());
Object obj = arg1.invoke(target, arg2);// 通过反射机制调用目标对象的方法
PerformanceMonitor.end();
return obj;
} }

首先,我们实现InvocationHandler接口,该接口定义了一个invoke方法,proxy最是最终生成的一个代理实例,一般不会用到,参数arg1是被代理目标实例的某个具体的方法,通过它可以发起目标实例方法的反射调用;参数arg2是通过被代理实例某一个方法的入参,在方法反射调用时候使用,通过代理将横切逻辑代码和业务类的代码编织到了一起。

我们在构造函数里通过target传入希望被代理的目标对象,将目标实例产地个method.inoke(),调用目标实例的方法。

4.通过Proxy结合PerformanceHandler创建UserService接口的代理实例:

package spring.aop.demo1;

import java.lang.reflect.Proxy;

public class UserServiceImpl implements UserService {

    @Override
public void removeUser(int userId) {
System.out.println("模拟删除用户:" + userId);
try {
Thread.currentThread().sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public static void main(String[] args) {
UserService userService = new UserServiceImpl();
// 将目标业务类和横切代码编织到一起
PerformanceHandler handler = new PerformanceHandler(userService); // 根据编织了目标业务类逻辑和性能监视横切逻辑的InvocationHandler实例创建代理实例
UserService proxy = (UserService) Proxy.newProxyInstance(userService
.getClass().getClassLoader(), userService.getClass()
.getInterfaces(), handler); proxy.removeUser(3); }
}

输出:

begin monitor...
模拟删除用户:3
end monitor...
spring.aop.demo1.UserServiceImpl.removeUser花费203毫秒

说明:上面的代码完成业务类代码和横切代码的编制工作,并生成了代理实例,newProxyInstance方法的第一个参数为类加载器,第二个参数为目标类所实现的一组接口,第三个参数是整合了业务逻辑和横切逻辑的编织器对象。使用JDK代理模式有一个限制,即它只能为接口创建代理实例,这一点我们可以从Proxy.newProxyInstance的方法签名中就可以看的很清楚,第二个参数interfaces就是需要代理实例实现的接口列表。

spring AOP详解二的更多相关文章

  1. Spring Aop 详解二

    这是Spring Aop的第二篇,案例代码很详解,可以查看https://gitee.com/haimama/java-study/tree/master/spring-aop-demo. 阅读前,建 ...

  2. 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理

    Spring AOP详解 . JDK动态代理.CGLib动态代理  原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...

  3. Spring AOP详解(转载)所需要的包

    上一篇文章中,<Spring Aop详解(转载)>里的代码都可以运行,只是包比较多,中间缺少了几个相应的包,根据报错,几经百度搜索,终于补全了所有包. 截图如下: 在主测试类里面,有人怀疑 ...

  4. Spring AOP详解及简单应用

    Spring AOP详解   一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址: ...

  5. 转:Spring AOP详解

    转:Spring AOP详解 一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址: ...

  6. [Spring学习笔记 5 ] Spring AOP 详解1

    知识点回顾:一.IOC容器---DI依赖注入:setter注入(属性注入)/构造子注入/字段注入(注解 )/接口注入 out Spring IOC容器的使用: A.完全使用XML文件来配置容器所要管理 ...

  7. Spring系列(四):Spring AOP详解

    一.AOP是什么 AOP(面向切面编程),可以说是一种编程思想,其中的Spring AOP和AspectJ都是现实了这种编程思想.相对OOP(面向过程编程)来说,提供了另外一种编程方式,对于OOP过程 ...

  8. Spring Aop 详解一

    Aop 是一个编程思想,最初是一个理论,最后落地成了很多的技术实现. 我们写一个系统,都希望尽量少写点儿重复的东西.而很多时候呢,又不得不写一些重复的东西.比如访问某些方法的权限,执行某些方法性能的日 ...

  9. Spring AOP详解 、 JDK动态代理、CGLib动态代理

    AOP是Aspect Oriented Programing的简称,面向切面编程.AOP适合于那些具有横切逻辑的应用:如性能监测,访问控制,事务管理以及日志记录.AOP将这些分散在各个业务逻辑中的代码 ...

随机推荐

  1. Nginx服务器301跳转到带www的域名的方法

    为什么要这么做? 我们的域名在做解析时经常会解析2个域名,即带www的和不带www的.这样做的目的是,当用户使用不带www的域名时,也可以正常访问你的网站.但是这样做的后果是,你站点主域名的PR值分散 ...

  2. SCCM Collection 集合获取计算机最后启动时间

    获取计算机客户端最后一次启动时间,我们可以通过多种来源获取,如活动目录组 ,而不仅仅是SCCM 收集,希望对您有所帮助,下面分享PowerShell 脚本 # 1 $CollectionName = ...

  3. Kail安装后的配置

    安装完Kail系统后进行简单的几项配置可以让使用更方便 VMware安装Kail系统这里就不介绍了,大家可以参考这个博客:http://www.cnblogs.com/xuanhun/p/568831 ...

  4. 卓越管理的实践技巧(2)成功的委派任务 Setup for Successful Delegation

    Setup for Successful Delegation 前文卓越管理的秘密(Behind Closed Doors)最后一部分提到了总结的13条卓越管理的实践技巧并列出了所有实践技巧名称的索引 ...

  5. UI与数据分离 与 UI的演进

    解藕的好处:UI内部模块能够灵活的变化. MVC或者三层架构着重强调了数据.业务逻辑和UI的分离. (MVC中的C只是UI和业务逻辑模块间的一个中转组件,理论上应该是个轻模块.) 以前的关注的解藕技术 ...

  6. [论文理解]SSD:Single Shot MultiBox Detector

    SSD:Single Shot MultiBox Detector Intro SSD是一套one-stage算法实现目标检测的框架,速度很快,在当时速度超过了yolo,精度也可以达到two-stag ...

  7. [web开发] Vue+Spring Boot 上海大学预约系统开发记录

    前端界面 使用Quasar将组件都排好,用好css. Quasar 入门 # 确保你在全局安装了vue-cli # Node.js> = 8.9.0是必需的. $ npm install -g ...

  8. 使用struts2实现文件上传与下载功能

    这个问题做了两天,在网上找了很多例子,但是还有一些功能没有实现,暂时先把代码贴出来,以后在做这方面的功能时在修改 文件上传: 一开始我在网上找到基于servlet+jsp环境写的文件上传,但是在将页面 ...

  9. 解决AjaxFileUpload中文化/国际化的问题。

    由微软官方提供的AjaxControlToolKit,在ASP.NET开发过程中,确实能够给开发者带来很多的便利,节约开发者的重复劳动.这套控件也是比较成熟的,在性能方面也不会太差,至少能够满足一般开 ...

  10. Bootstrap历练实例:带链接的警告

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...