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. sqlserver2012 密码过期问题

    昨天登录系统突然连不上数据库了看了看报错内容提示是sqlserver的用户密码过期,那么就简单记录下操作,方便孩子后解决 (1)首先打开sql Management Studio 2012 顺便提一下 ...

  2. Shiro第二篇【介绍Shiro、认证流程、自定义realm、自定义realm支持md5】

    什么是Shiro shiro是apache的一个开源框架,是一个权限管理的框架,实现 用户认证.用户授权. spring中有spring security (原名Acegi),是一个权限框架,它和sp ...

  3. jmeter通过BeanShell 脚本,实现对http请求参数的加密

    jmeter一直是一款很好的接口和性能测试工具,它是开源的,不需要为此支付任何费用,而且可以下载源码,可以在修改源代码并在此基础上拓展自己的功能或插件,它可以跟ant和jenkins结合起来搭建自己的 ...

  4. net core 安装web模板

    ---恢复内容开始--- 今天想试试在Linux用C#开发WebAPI,查了下,要用: dotnet new -t Web 来建立工程,结果我试了下,出来这段: Invalid input switc ...

  5. cocos2dx 播放gif

    起因 或许有人会说,cocos2dx中直接帧动画就行了用什么GIF. 起因是为游戏内部要用到第三方平台的头像,而第三方平台的头像大多都是用到Gif,所以才会有了这个需求 过程 查了各种文档都没找到.但 ...

  6. ArrayListd的长度问题

    namespace ArrayListd的长度问题{ class Program { static void Main(string[] args) { //需要的参数是object类型 //alt+ ...

  7. Linux入门之常用命令(11) 系统监控 vmstat top

    vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况.这个命令是我查看Linux/Unix最 ...

  8. JSP入门3 Servlet

    需要继承类HttpServlet 服务器在获得请求的时候会先根据jsp页面生成一个java文件,然后使用jdk的编译器将此文件编译,最后运行得到的class文件处理用户的请求返回响应.如果再有请求访问 ...

  9. End up with More Teams UVA - 11088

    End up with More Teams Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu ...

  10. Windows下MySQL5.6.21安装步骤

    01.把 mysql-advanced-5.6.17-winx64.zip 解压到自定义 D:\mysql-5.6.17-W64 或 D:\mysql-advanced-5.6.17-winx64 目 ...