`
Jummy
  • 浏览: 61249 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

从JDK动态代理看Spring之AOP实现

阅读更多

 

  Spring 缺省使用J2SE 动态代理(dynamic proxies 来作为AOP 的代理。这样任何接口都可以被代理。

Spring 也支持使用CGLIB 代理. 对于需要代理类而不是代理接口的时候CGLIB 代理是很有必要的。 如果一个业务对象并没有实现一个接口,默认就会使用CGLIB------- 这是Spring Framework 开发手册中对AOP 的一个简要概括

  其实个人看来 Spring Framework 是个大杂烩,它提供了许多框架的接口。当然它自己也有一套 MVC 框架。其中最为常见也最为重要也就是 IoC AOP 。所谓的 LightWeight Container( 轻量级 ) 就是整个容器的倾入性极低或者没有倾入性让对象与对象之间的关系通过配置来体现避免了对象之间的直接调用 ( 当然这不是轻量级容器的完全定义 ), 轻量级带来的就是单例和工厂的有效减少。嗯 …IoC 是一种思想,它的实现有依赖注入和依赖查找。开发中遇到比较多的就是依赖注入 Spring 所提供的方法有 (Setter 方法注入,构造器注入 以及接口注入 ) 三种方法的使用程度也如我所列的顺序一样,当然各人所好不同。

  AOP 就是面向切面编程,平时我们所面对的都是 OO 那是一个纵向的编程思想,而 AOP 的出现使得面向的切面 ( 即横向编程 ) 的理念得到了众多的认可。其实 AOP 的思想早期在 EJB( 个人对 EJB 了解不是很够,这里就不在细说 ) 中也得以体现,最为常用的就是声明式事务的使用。 For Example :比如我声明这个类中所有以 save 开头的接口都用事务,所以当其被调用时开启事务,成功后提交事务,失败了就回滚事务。那 Spring 中所提供的 AOP EJB 中的所采用的拦截机制有什么区别呢?对早期的 EJB(3.0 之前 ) 来说,你只有实现了 EJB 才有该功能而 Spring 则不同, Spring 对普通的 POJO 都可以实现 AOP 。这就是为什么 EJB2.x 以失败而告终,所以当 EJB3.0 卷土重来时它就加入对 Spring 的集成。这也是开源的一大优势呐。

  一下说的有点多了,吐出来的知识点可能也多了点。还是回归主题吧。谈谈 AOP Spring 中默认是通过 JDK 动态代理来是 AOP 。其实你要是对 JDK 动态代理理解烂熟于心我想我下面的内容你是不用看了。如果你还是不怎么熟悉,希望大家一起学习。我把自己学习 AOP 的心得写一写,以示例为主便于理解,讲的不好还希望大家指点指点 …..

  JDK 动态代理分静态代理和动态代理,其中静态代理适用于代理比较少的情形它是一个实实在在的代理类所以当代理比较多的时候你得去编写许多代理类效率自然就下降了。而动态是在运行时才生产的,当你调用时才生成代理当然它的前提是继承接口 (invocationHandler) 实现 invoke() 方法。下面我们看个动态代理的例子:(一个很普通的 JAVA PROJECT

                <!----><!---->

这个 project 中,我写了:一个接口: UserManagery

接口的实现类: UserManageryImpl

代理类: SecurityHandler

以及一个简单的客户端: Client

 

 

 

 

先看接口:很普通,就是几个方法。

           <!----><!---->

package com.jummy.spring;

public interface UserManager {
 public void  addUser(int id,String name);
 public void delUser(int id);
 public void modifyUser(int id,String name,int age);
}     

 

接着看实现类:也很普通,各个方法的具体实现。

package com.jummy.spring;

public class UsreManagerImpl implements UserManager {

	public void addUser(int id, String name) {
		/*
		 * 比如说要在添加之前做一些安全性检查,当然最原始的做法时在调用方法之前写一些验证代码。 Of
		 * course你可以将验证专门抽取出来写成一个方法甚至一个类,然后进行调用。 For example
		 * 该类中抽取出一个scurity()的方法用于验证,不过你每次验证都需要如下的调用
		 * 如此来若需要的调用的方法多了,方法甚至类就不再单一了。甚至一眼看不出这到底是一个具体功能模块
		 * 还是验证模块。这样类就不再便于管理(方法太多)。于是就出现了代理,通过代理类来实现那些不是主要的功能
		 * 这样模块的功能就很清晰,同时你在不修改原先类的情况下给该类添加功能实现
		 */
		// security();
		System.out.println("---UsreManagerImpl中的addUser方法的实现-----");
	}

	public void delUser(int id) {
		System.out.println("-----delUser方法的实现-----");
	}

	public void modifyUser(int id, String name, int age) {
		System.out.println("----modifyUser方法的实现-----");
	}

	public void security() {
		System.out.println("-----调用security方法-------");
	}
}
 

只是此时提及一下代理的作用,比如说我在调用 ADD() 方法之前需要进行安全验证(这是个很常规的步骤)传统的编码方式就是将验证方法直接写在类中,当然这无可厚非但是当需要调用的方法不断增加时整个类的就会很模糊。有人说我将需要验证的方法单独抽象出来成一个类。但这样你也要在原来的类中不断的用实例化这个验证类,这也存在所需方法不断增多的情况。这样我们就考虑 又要调用验证又要不去破坏(修改)原来类的代码。所以代理就粉墨登场,通过一个代理类来实现这个功能。

  看一下代理类:这是关键,理解这个你就理解了 AOP

package com.jummy.spring;
/*
 * 创建一个专门的执行security方法的类。实现InvocationHandler接口
 * 
 * 
 * 
 * 
 */
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class SecurityHandler implements InvocationHandler {
    //适合于所有的对象
	private Object object;
	
	//通过构造方法将参数传递
	public Object newProxy(Object object){
		this.object=object;
		//生成动态代理 3个参数
		return Proxy.newProxyInstance(object.getClass().getClassLoader(),
				                      object.getClass().getInterfaces(),
				                      this);
	}
	public Object invoke(Object arg0, Method method, Object[] arg2)
			throws Throwable {
		//代理类在调用任何方法都先调用invoke()方法,这里的invoke()方法中先执行checkSecurity()方法
		checkSecurity();
		//这里可以查看invoke中调用方法的名称
		System.out.println("method name="+method.getName());
		//该参数是一个数组类型Object[] arg2
		for(int i=0;i<arg2.length;i++){
			System.out.println(arg2[i]);
		}
		Object result=null;
		//下面才是真正调用的方法,将对象添加到invoke 方法中
		try{
		result=method.invoke(object, arg2);
		//方法执行之后,也可以自定义方法
		}catch(Exception e){
			e.printStackTrace();
		}
		return result;
	}
	public void checkSecurity(){
		System.out.println("-----checkSecurity------");
	}

}
 

  下面我们来细细分析这个类,首先实现接口 invocationHandler ,还有方法 invoke(). 当代理类产生代理之后,在调用所有的方法之前都会先执行 invoke() 方法(想到 AOP 中的 BeforeAdvice 了吗?)。方法 checkSecurity() 就是我提到的验证方法,我们写在代理类中,而你在原先类中去看不到他的具体引用。其中 method.getName() 是获得所传入对象所调用的方法的方法名。 ( 假如你只需要对名称为 addUser 的方法进行单独验证,加个条件判断不就可以了麽,有点 Spring 的味道了吗? ) 再看, method.invoke() 这才是真正调用的方法,在到这一步之前我已经添加了许多验证方法了,而这在原先类中却什么都看不到一切我们都在代理类中实现的。这就避免了对原先类的修改了。当然这个方法调用之后,你还可以继续添加方法(想到了 AOP afteradvice 通知了吗?)

  当你所需要的方法不断增多是你不是可以写成 xml 文件么,通过 xml 文件来配置方法。 Spring 大致就是从这个思想演变过来的。

最后看客户端:

package com.jummy.spring;

public class Client {
  public static void main(String args[]){
	  SecurityHandler handler=new SecurityHandler();
	  UserManager userManager=(UserManager)handler.newProxy(new UsreManagerImpl());
	  userManager.addUser(19861018, "Jummy");
  }
}
 

通过代类理的实例来代理原先类( newProxy(new UserManagerImple()) . 然后你再去调用 addUser() 方法。所有的验证都添加进去了。

 

  可能讲了半天有的朋友还只是说没有 AOP ,其实要讲 AOP 不一定要把 AOP 啃个遍,关键是要理解如何实现 AOP 如何区别于 OOP 的纵向编程。当然, OO 起家的我觉得 AOP 始终是个补充,万事无绝对。

 

             

 

 

 

 

9
2
分享到:
评论
8 楼 baixiaozhe 2009-03-01  
谢谢了 美女
7 楼 yiminghe 2008-12-15  
很好,收藏
6 楼 willim 2008-12-12  
不错,支持楼主
5 楼 netfork 2008-12-02  
楼主的说明很不错,我曾利用动态代理,对resultset进行了数据过滤。
现在想想都还很有成就感!
4 楼 amcucn 2008-10-17  
不错,学习一下!
3 楼 easion_zms 2008-10-17  
谢谢!学习中呢,收获不小!!!!
2 楼 Jummy 2008-10-16  
最近一直和一个老同学弄着网络广告玩,大家有兴趣的也点进去看看吧。
http://9gao.com/cf.aspx?24&jummy
1 楼 Jummy 2008-10-16  
文章写的还是有待商榷,昨晚下班回去做完饭吃饭完就开始写的,一下子做到10点多。可能还有好多疏漏之处。毕竟这每一个字都是我实实在在敲出来了的。
其实本来想直接写个SPRING的例子然后随便谈上个海阔天空,后来加以细想。用过SPRING 的人谁不会写配置文件,谁不会装载架包。实在没有那个班门弄斧的必要。
后来,既然大家都知道WHAT但有人知道WHY吗?重要的的整个framework的理解而不是按部就班。当然以后有空我也会继续写下去,知道个究竟而不是浅尝辄止。
希望看的人,给提提意见。大家共同进步。

相关推荐

    JDK动态代理 spring aop 的原理

    总的来说,JDK动态代理是Spring AOP实现的基础,它允许我们在运行时动态创建代理对象,实现对方法调用的拦截和增强。Spring AOP则在此基础上提供了更高级的抽象,让我们可以方便地定义和管理切面,从而实现更灵活的...

    从JDK动态代理到spring AOP

    本篇将详细探讨JDK动态代理和Spring AOP,以及它们在实际应用中的作用。 首先,JDK动态代理是Java提供的一种在运行时创建代理对象的技术。它允许我们在不修改原有类的基础上,为已有接口添加额外的功能。动态代理的...

    spring之AOP(动态代理)

    在Spring中,AOP主要通过两种动态代理技术实现:JDK动态代理和CGLIB动态代理。 首先,让我们详细了解一下JDK动态代理。JDK动态代理基于Java的接口实现,它适用于目标对象实现了至少一个接口的情况。在运行时,JDK...

    代理模式,JDK动态代理,SpringAOP来龙去脉

    在Java中,我们可以使用JDK的动态代理或者Spring AOP来实现代理模式。 JDK动态代理主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。Proxy类是生成代理对象的工厂,而...

    反射实现 AOP 动态代理模式(Spring AOP 的实现原理)

    Spring AOP支持不同的代理策略,包括JDK动态代理和CGLIB代理。如果被代理的类没有实现接口,Spring AOP会采用CGLIB来生成代理对象。CGLIB(Code Generation Library)是一个开源的代码生成库,它允许运行时在内存中...

    Spring-AOP-JDK动态代理

    本篇将详细讲解Spring中的AOP实现,特别是JDK动态代理的应用。 首先,我们要了解什么是AOP(Aspect Oriented Programming,面向切面编程)。AOP是一种编程范式,旨在解决应用程序中分散的、横切关注点的问题,如...

    Spring Aop的底层实现技术 --- Jdk动态代理原理

    Spring AOP 的底层实现技术 --- Jdk 动态代理原理 JDK 动态代理是 Spring AOP 的底层实现技术,允许开发者在运行期创建接口的代理实例。在 JDK 1.3 以后,JDK 动态代理技术提供了实现 AOP 的绝好底层技术。JDK 动态...

    spring_aop之JDK的动态代理

    在Spring AOP中,当目标对象实现了至少一个接口时,Spring会使用JDK的动态代理来创建代理对象。这是因为JDK的动态代理只适用于实现了接口的类,它通过生成一个与目标类接口相同的新类来实现代理。这个新类在运行时被...

    Spring框架中JDK动态代理和cglib动态代理

    在 Spring AOP 框架中,默认情况下,Spring 会选择使用 JDK 动态代理,但是如果目标对象没有实现接口,Spring 就会选择使用 CGLIB 动态代理。这种机制可以确保 Spring AOP 框架可以代理任何类型的对象,无论它是否...

    AOP之JDK动态代理和CGLib动态代理

    Spring框架是AOP实现的一个典范,它提供了两种主要的动态代理方式:JDK动态代理和CGLib动态代理。 **JDK动态代理**: JDK动态代理基于Java的反射API实现,适用于接口代理。当目标对象实现了至少一个接口时,Spring...

    模拟spring aop【一】基于jdk动态代理实现的aop

    本篇文章将探讨如何通过JDK动态代理实现Spring AOP的基础知识。 首先,我们要理解什么是JDK动态代理。在Java中,动态代理机制允许我们在运行时创建一个实现了特定接口的新类。这个新类的实例可以代理目标对象,执行...

    spring jdk动态代理

    Spring AOP允许我们通过代理来实现横切关注点,如日志、事务管理等,而JDK动态代理则是Spring AOP实现的一种方式。本文将深入探讨Spring如何利用JDK动态代理技术来实现这一功能,并通过实例解析其底层实现。 首先,...

    死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理(csdn)————程序.pdf

    在 Spring 中,AOP 的实现主要依赖于代理模式,有两种代理方式:JDK 动态代理和 CGLIB 动态代理。 JDK 动态代理是基于接口的,它要求被代理的目标对象必须实现至少一个接口。Spring 使用 `java.lang.reflect.Proxy`...

    Java动态代理(Spring Aop原理)

    在Spring框架中,AOP(面向切面编程)就是基于Java动态代理来完成的,用于实现横切关注点,如日志、事务管理等。这篇博客的文章链接虽然没有给出具体内容,但我们可以根据Java动态代理和Spring AOP的基本概念来深入...

    使用动态代理演示Spring的AOP编程原理

    为了说明Spring的AOP原理,本人使用代理模式中的动态代理完成演示AOP编程的原理的演示。相信,如果你耐心看完整个程序(几乎一行注释一行代码),那么你对Spring这个东西就不是觉得有什么神秘了! 阅读对象:凡是喜爱...

    spring-aop.jar各个版本

    spring-aop-1.1.1.jar spring-aop-1.2.6.jar spring-aop-1.2.9.jar spring-aop-2.0.2.jar spring-aop-2.0.6.jar spring-aop-2.0.7.jar spring-aop-2.0.8.jar spring-aop-2.0.jar spring-aop-2.5.1.jar spring-aop-...

    浅谈JDK动态代理与CGLIB代理去区别

    在"通过Configuration文件实现AOP.docx"文档中,可能会详细讲述如何在Spring配置文件中配置AOP代理,包括如何选择使用JDK动态代理还是CGLIB。 总结来说,JDK动态代理简单且高效,适合接口驱动的设计,而CGLIB适用于...

    springAOP配置动态代理实现

    动态代理则是Spring AOP实现的核心技术之一,它允许我们在运行时创建具有额外行为的对象。下面将详细阐述Spring AOP的配置以及动态代理的实现。 一、Spring AOP基础知识 1. **什么是AOP**:AOP是一种编程范式,...

    Spring AOP实现机制

    Spring AOP主要通过两种方式实现:JDK动态代理和CGLIB代理。 - **JDK动态代理**: - 当目标对象实现了至少一个接口时,Spring会使用JDK的java.lang.reflect.Proxy类创建一个代理对象。 - 代理对象在调用实际方法...

Global site tag (gtag.js) - Google Analytics