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. python+selenium之断言Assertion

    一.断言方法 断言是对自动化测试异常情况的判断. # -*- coding: utf-8 -*- from selenium import webdriver import unittest impo ...

  2. python爬虫之路——初识lxml库和xpath语法

    lxml库:是xml解析库,也支持html文档解析功能,实用功能:自动修正补全html代码. 使用流程:①导入lxml中的etree库,②利用etree.HTML(文件名)或etree.parse(本 ...

  3. 重温Javascript(一)-基本概念

    工作中要用到JavaScript,一组复习笔记. 一些看法 1. 想想JavaScript目前最常用的宿主环境,浏览器或者服务端V8,都是单线程,所以不用过多的考虑并发的问题,如果是协程来实现异步的方 ...

  4. Spark集群任务提交

    1. 集群管理器 Spark当前支持三种集群管理方式 Standalone—Spark自带的一种集群管理方式,易于构建集群. Apache Mesos—通用的集群管理,可以在其上运行Hadoop Ma ...

  5. C++ 值传递&引用&地址

  6. 剑指offer38 数字在排序数组中出现的次数

    这种方法没用迭代,而是使用了循环的方式 class Solution { public: int GetNumberOfK(vector<int> data ,int k) { if(da ...

  7. springmvc的第一个程序

    文中用的框架版本:spring 3,hibernate 3,没有的,自己上网下. web.xml配置: <?xml version="1.0" encoding=" ...

  8. 第四次作业:Windows各种基本应用的命令处理方法

    删除文件夹命令? rd (remove directory) 如何给文件夹重新命名? ren (rename) 如何在文件夹中建立文件夹? md swift\a 如何用命令查看文本文件的内容? typ ...

  9. LaTeX中常用数学符号总结

    博主一些小小的总结,以后会继续更的. 某个传送门. ⎝⎛•‿•⎞⎠⎝⎛•‿•⎞⎠⎝⎛•‿•⎞⎠ 1.左右一个$: 1+1=2 $1+1=2$ ($3$及以后的都需要$) 2.左右两个$: 1+1=2 ...

  10. 【NOIP提高A组模拟2018.8.14】 区间

    区间加:差分数组修改 O(n)扫描,负数位置单调不减 #include<iostream> #include<cstring> #include<cstdio> # ...