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课程设计 猜数游戏团队博客

    1.团队成员介绍(需要有照片) 曾飞远(组长):网络1513 201521123080 江鹭涛(组员):网络1513 201521123075 2. 项目git地址 3. 项目git提交记录截图(要体 ...

  2. jsp+servlet对于单选按钮和复选框取值并且存放到数据库中

    index.jsp <form action="index.gj?method=toradio" method="post"> <div al ...

  3. 04面向对象编程-01-创建对象 和 原型理解(prototype、__proto__)

    1.JS中对象的"不同":原型概念 从Java中我们可以很好地去理解 "类" 和 "实例" 两个概念,可是在JavaScript中,这个概念 ...

  4. 纯css隐藏移动端滚动条解决方案(ios上流畅滑动)

    纯css隐藏移动端滚动条解决方案(ios上流畅滑动) html代码展示(直接复制代码保存至本地文件运行即可): <!DOCTYPE html> <html lang="en ...

  5. 框架应用:Mybatis (一) - 入门案例

    ORM框架 在实际开发中,工程中本质的任务是从数据库中获取数据,然后对数据进行操作,又或者写入数据.开发时语言是大多是面向对象的工程语言,这个时候就必须进行工程语言和数据库连接语言的转换,也就是所谓的 ...

  6. Coder的好伙伴Github

    网络越来越发达,各式各样的网盘.云存储也走进日常生活,  在老师的指导下,我第一次接触了GitHub. 什么是Github? Github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一 ...

  7. nodejs 初次链接 mongodb 的详细细节

    时间  2016-06-2613:05:16 在前端的学习也有一段时间了,学习了html,css,javascript,jqery,ajax,php,mysql,学习了这些,了解了一些皮毛,也没有什么 ...

  8. AngularJS–Scope(作用域)

    点击查看AngularJS系列目录 转载请注明出处:http://www.cnblogs.com/leosx/ Scope Scope 是一个应用程序的模块的对象.它是表达式的执行上下文.它充斥在DO ...

  9. 移动端touch事件实现页面弹动--小插件

    动手之前的打盹 说实话真的是好久没有更新博客了,最近一直赶项目,身心疲惫:最关键的是晚上还要回去上一波王者,实在是忙啊! 这周下来,清闲了些许,或许是因为要到国庆的缘故吧,大家都显得无精打采.俗话说的 ...

  10. thinkphp的select和find的区别

    hinkphp是比较好的php开发框架,能比较快速的开发MVC架构的管理系统,我们需要用到 select()和find()方法,两个方法都能返回数据集数组,但有什么不同呢?先看一下我的代码对比:$te ...