文档章节

Java 动态代理实践AOP

_
 _OUTMAN_
发布于 2016/06/26 11:05
字数 737
阅读 47
收藏 5

大家都知道Spring中AOP是通过Java动态代理实现的,今天就来简单学习下demo。

Java动态代理主要有两个核心类,InvocationHandler和Proxy。

/**
 * {@code InvocationHandler} is the interface implemented by
 * the <i>invocation handler</i> of a proxy instance.
 *
 * <p>Each proxy instance has an associated invocation handler.
 * When a method is invoked on a proxy instance, the method
 * invocation is encoded and dispatched to the {@code invoke}
 * method of its invocation handler.
 *
 * @author      Peter Jones
 * @see         Proxy
 * @since       1.3
 */
public interface InvocationHandler

所有的Handler类要实现InvocationHandler接口,并关联到Proxy实例上,最后会分发到InvocationHandler的invoke方法上。

/**
 * {@code Proxy} provides static methods for creating dynamic proxy
 * classes and instances, and it is also the superclass of all
 * dynamic proxy classes created by those methods.
 *
 * <p>To create a proxy for some interface {@code Foo}:
 * <pre>
 *     InvocationHandler handler = new MyInvocationHandler(...);
 *     Class proxyClass = Proxy.getProxyClass(
 *         Foo.class.getClassLoader(), new Class[] { Foo.class });
 *     Foo f = (Foo) proxyClass.
 *         getConstructor(new Class[] { InvocationHandler.class }).
 *         newInstance(new Object[] { handler });
 * </pre>
 * or more simply:
 * <pre>
 *     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
 *                                          new Class[] { Foo.class },
 *                                          handler);
 * </pre>
 *
 ****************************
 */
public class Proxy implements java.io.Serializable

通过该类的静态方法创建要动态代理的类。

下面看下demo

1. 先创建一个接口

public interface TargetInterface {
	int targetMethod(int num);
}

2. 实例化该接口

public class TargetClass implements TargetInterface {
	@Override
	public int targetMethod(int number) {
		System.out.println("调用目标类的方法targetMethod...");  
        return number;  
	}
}

3. 创建代理处理类,InvocationHandler子类

public class ProxyHandler implements InvocationHandler {
	Object concreteClass;
	public ProxyHandler(Object concreteClass) {
		this.concreteClass = concreteClass;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
        System.out.println("proxy:"+proxy.getClass().getName());  
        System.out.println("method:"+method.getName());  
        System.out.println("args:"+args[0].getClass().getName());  

        System.out.println("Before invoke method...");  
        Object object = method.invoke(concreteClass, args);
        System.out.println("After invoke method...");  
        return object;  
	}
}
proxy:  指代我们所代理的那个真实对象
method: 指代的是我们所要调用真实对象的某个方法的Method对象
args:  指代的是调用真实对象某个方法时接受的参数
public class Example {
	public static void main(String[] args) {
		TargetClass cc = new TargetClass();
		InvocationHandler ih = new ProxyHandler(cc);
		TargetInterface tf = (TargetInterface) Proxy.newProxyInstance(cc.getClass().getClassLoader(), cc.getClass().getInterfaces(), ih);
		
		int i = tf.targetMethod(5);
	}
}
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException

loader:  一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
interfaces:  一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
h:  一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上

注意:通过 Proxy.newProxyInstance 创建的代理对象是在jvm运行时动态生成的一个对象,它并不是我们的InvocationHandler类型,也不是我们定义的那组接口的类型,而是在运行是动态生成的一个对象,并且命名方式都是这样的形式,以$开头,proxy为中,最后一个数字表示对象的标号

动态代理有个缺陷,就是创建时需要参数interfaces,即被代理的类,需要实现该接口。

© 著作权归作者所有

_
粉丝 22
博文 133
码字总数 63959
作品 0
海淀
程序员
私信 提问
3.2 Spring AOP的设计与实现

JVM的动态代理特性 在Spring AOP实现中,使用的核心技术是动态代理,这实际上是JDK的一个特性(JDK1.3以上的版本有这个特性)。通过JDK的动态代理特性,可以为任意Java对象创建代理对象,对于...

edwardGe
2018/05/30
38
0
Spring AOP 实现原理与 CGLIB 应用

AOP(Aspect Orient Programming),也就是面向方面编程,作为面向对象编程的一种补充,专门用于处理系统中分布于各个模块(不同方法)中的交叉关注点的问题,在 Java EE 应用中,常常通过 ...

IBMdW
2012/09/26
1K
2
Java代理-Javassist

代理 (agent) 是在你的main方法前的一个拦截器 (interceptor),也就是在main方法执行之前,执行agent的代码。agent的代码与你的main方法在同一个JVM中运行,并被同一个system classloader装载...

ksfzhaohui
2014/09/02
2K
0
Spring的事务管理难点剖析(6):特殊方法成漏网之鱼

由于Spring事务管理是基于接口代理或动态字节码技术,通过AOP实施事务增强的。虽然Spring还支持AspectJ LTW在类加载期实施增强,但这种方法很少使用,所以我们不予关注。 对于基于接口动态代...

icheer
2012/07/17
59
0
Spring 事务管理高级应用难点剖析: 第 2 部分

Spring 抽象的 DAO 体系兼容多种数据访问技术,它们各有特色,各有千秋。像 Hibernate 是非常优秀的 ORM 实现方案,但对底层 SQL 的控制不太方便;而 iBatis 则通过模板化技术让您方便地控制...

红薯
2010/03/28
801
1

没有更多内容

加载失败,请刷新页面

加载更多

PyTorch入门笔记一

张量 引入pytorch,生成一个随机的5x3张量 >>> from __future__ import print_function>>> import torch>>> x = torch.rand(5, 3)>>> print(x)tensor([[0.5555, 0.7301, 0.5655],......

仪山湖
13分钟前
1
0
OSChina 周二乱弹 —— 开发语言和语言开发的能一样么

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @花间小酌:#今日歌曲推荐# 分享The Score的单曲《Revolution》 《Revolution》- The Score 手机党少年们想听歌,请使劲儿戳(这里) @批判派...

小小编辑
今天
1K
17
oracle ORA-39700: database must be opened with UPGRADE option

ORA-01092: ORACLE instance terminated. Disconnection forced ORA-00704: bootstrap process failure ORA-39700: database must be opened with UPGRADE option 进程 ID: 3650 会话 ID: 29......

Tank_shu
今天
3
0
分布式协调服务zookeeper

ps.本文为《从Paxos到Zookeeper 分布式一致性原理与实践》笔记之一 ZooKeeper ZooKeeper曾是Apache Hadoop的一个子项目,是一个典型的分布式数据一致性的解决方案,分布式应用程序可以基于它...

ls_cherish
今天
4
0
聊聊DubboDefaultPropertiesEnvironmentPostProcessor

序 本文主要研究一下DubboDefaultPropertiesEnvironmentPostProcessor DubboDefaultPropertiesEnvironmentPostProcessor dubbo-spring-boot-project-2.7.3/dubbo-spring-boot-compatible/au......

go4it
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部