1、静态代理,实现代码如下,实际上是对装饰器模式的一种应用

interface UserManager {
public void addUser();
} class UserManagerImpl implements UserManager {
public void addUser() {
System.out.println("raw addUser");
}
} class UserManagerImplProxy implements UserManager {
private UserManager userManager; public UserManagerImplProxy(UserManager userManager) {
this.userManager = userManager;
} public void addUser() {
System.out.println("in proxy");
userManager.addUser();
}
}
public class ProxyTest {
public static void main(String args[]) {
UserManager userManager = new UserManagerImplProxy(new UserManagerImpl());
userManager.addUser();
}
}

2、动态AOP,借助 java.lang.reflect.InvocationHandler接口 和 java.lang.reflect.Proxy 类实现

java.lang.reflect.InvocationHandler接口的定义如下:

public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}

Object proxy:被代理的对象

Method method:要调用的方法

Object[] args:方法调用时所需要参数

invoke 方法用于切面处理,调用相应的方法

java.lang.reflect.Proxy类的定义如下:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException

CLassLoader loader: 类的加载器

Class<?> interfaces: 得到全部的接口

InvocationHandler h: 实现 InvocationHandler 接口的子类的实例

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; interface UserManager {
public void addUser();
} class UserManagerImpl implements UserManager {
public void addUser() {
System.out.println("raw addUser");
}
} class UserManagerImplProxy implements InvocationHandler { private Object targetObject; public void log() {
System.out.println("message info");
} public Object createProxyInstance(Object targetObject) {
this.targetObject = targetObject;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
log();
Object ret = method.invoke(targetObject, args);
return ret;
}
}
public class ProxyTest {
public static void main(String args[]) {
UserManagerImplProxy proxy = new UserManagerImplProxy();
UserManager manager = (UserManager) proxy.createProxyInstance(new UserManagerImpl());
manager.addUser();
}
}

3、动态代码字节生成

CGLib是动态代码字节生成的实现,它封装字节码生成工具Asm,原理是在运行期间目标字节码加载后,生成目标类的子类,将切面逻辑加入到子类中,所以使用Cglib实现AOP不需要基于接口。cglib 的核心是实现 MethodInterceptor 接口,使用 intercept() 方法进行面向切面的处理,调用相应的通知。其中 cglib 中有一个 Enhancer 类,可以使用他快速的创建一个代理类。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; interface UserManager {
public void addUser();
} class UserManagerImpl implements UserManager {
public void addUser() {
System.out.println("raw addUser");
}
} class CGLIBProxyFactory implements MethodInterceptor{
// 要放回的代理对象
private Object obj; public Object createProxy(Object obj) {
// 把传进来的代理对象赋值给obj
this.obj = obj;
Enhancer enhancer = new Enhancer();
// 需要为其实例指定一个父类,也就是我们 的目标对象,那么我们新创建出来的对象就是目标对象的子类,有目标对象的一样
enhancer.setSuperclass(this.obj.getClass());
// 除此之外,还要指定一个回调函数,这个函数就和Proxy的 invoke()类似
enhancer.setCallback(this);
return enhancer.create(); } public void log() {
System.out.println("message info");
} @Override
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object proxyObject = null;
UserManagerImpl um = (UserManagerImpl) obj;
log();
proxyObject = methodProxy.invoke(um, args);
return proxyObject;
} } public class ProxyTest {
public static void main(String args[]) {
CGLIBProxyFactory gb = new CGLIBProxyFactory();
UserManager manager = (UserManager)gb.createProxy(new UserManagerImpl());
manager.addUser();
}
}

AOP的实现的几种方式的更多相关文章

  1. 利用aop插入异常日志的2种方式

    AOP是面向切面编程,利用这个技术可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各个部分的耦合性降低,提高代码的可重用性,同时提高开发效率(来自百度百科). Spring AOP有两种实现方式,一 ...

  2. Spring事务配置的五种方式(转载)

    Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分. DataSo ...

  3. Spring事务配置的五种方式

    Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分. DataSo ...

  4. 配置spring事务管理的几种方式(声明式事务)

    Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分. DataSo ...

  5. Spring事务配置的五种方式 -- 越往后需要Spring版本越高

    第五种 基本零配置  个人感觉第四种也可以 Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式, ...

  6. Spring 事务配置5种方式

    Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分. DataSo ...

  7. Spring事务配置的五种方式(转)

    前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的. ...

  8. Spring事务配置的五种方式(转发)

    Spring事务配置的五种方式(原博客地址是http://www.blogjava.net/robbie/archive/2009/04/05/264003.html)挺好的,收藏转发 前段时间对Sp ...

  9. Spring事务配置的五种方式 巨全!不看后悔,一看必懂!

    前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的. ...

随机推荐

  1. Java课程设计 201521123078

    计时器 掌握java图形界面操作以及多线程技术. 1.Mythread1 写一个类Mythread1实现Runnable,当需要开一个线程时就是用这个类.其中的run()通过标记flag和循环实现时间 ...

  2. 银河麒麟操作系统打开VMware报vmmon无法编译

    使用银河麒麟操作系统打开VMware可能会报vmmon无法编译 这个时候... 将/usr/src/linux-headers-xxx/include/miscdevice.h第71行void改为in ...

  3. linux加载与使用ko驱动

    linux驱动和有两种形式: 1:编译到内核 2:编译为ko模块 这里记录下ko模块使用方法. 首先cd到/var/lib/(内核版本)/drivers/ 在这里面找到要装载的模块ko文件 modpr ...

  4. Eclipse 多行复制并且移动失效

    Eclipse  有个好用的快捷键  即 多行复制 并且移动 但是 用 Win7 的 电脑 的 时候 发现屏幕 在 旋转 解决方案: 打开Intel的显卡控制中心 把旋转  的 快捷键 进行更改 就好 ...

  5. 软件工程个人第二小项目——wc

    github源码和工程文件地址:https://github.com/HuChengLing/wc 基本要求:要实现wc的基本功能即文件中字符数.单词数.行数的统计. 主要功能:文件中字符数.单词数. ...

  6. KMP算法的来龙去脉

    1. 引言 字符串匹配是极为常见的一种模式匹配.简单地说,就是判断主串TT中是否出现该模式串PP,即PP为TT的子串.特别地,定义主串为T[0-n−1]T[0-n−1],模式串为P[0-p−1]P[0 ...

  7. Spring+SpringMVC+MyBatis整合进阶篇(四)RESTful实战(前端代码修改)

    前言 前文<RESTful API实战笔记(接口设计及Java后端实现)>中介绍了RESTful中后端开发的实现,主要是接口地址修改和返回数据的格式及规范的修改,本文则简单介绍一下,RES ...

  8. U方法

    U方法用于完成对URL地址的组装,特点在于可以自动根据当前的URL模式和设置生成对应的URL地址,格式为:U('地址','参数','伪静态','是否跳转','显示域名');在模板中使用U方法而不是固定 ...

  9. 【转】Keberos认证原理

    前几天在给人解释Windows是如何通过Kerberos进行Authentication的时候,讲了半天也别把那位老兄讲明白,还差点把自己给绕进去.后来想想原因有以下两点:对于一个没有完全不了解Ker ...

  10. 洗礼灵魂,修炼python(6)--活起来的代码+列表

    活起来的用法: 使用input内置函数 注意python2中和python3中,input函数是不太一样的,python2中,input用户传入什么类型就是什么类型而python3中,不管传入什么类型 ...