`

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

阅读更多
这里我们学习一下代理模式,JDK的动态代理,以及以JDK为基础的springAOP实现
代理模式:类结构的模式,优点就是不需要更改原有类(被代理类)就能增强原有类(被代理类)的功能,缺点就是必须实现原有类(被代理类)的接口
JDK的动态代理:优点就是不必“复制”原有类(被代理类)接口实现类,缺点就是必须为每个被代理类实现几乎一样的方法
springAOP:优点就是采用springIOC,JDK动态代理等技术来实现AOP机制
我们展示一个类的几个方法,分别采用代理模式,JDK动态代理,springAOP机制来做些额外功能
这里定义一个接口,一个实现类
package com.fruitking.proxy;

/**
 * 汽车服务类接口
 * @author fruitking
 * @since 2010-02-23
 */
public interface CarService {
	
	/**
	 * 启动汽车
	 */
	public void start();
	
	/**
	 * 获得汽车搭载人数
	 * @return
	 */
	public int getLoadAmount();
	
	/**
	 * 设置驾驶员
	 * @param driver
	 * @return
	 */
	public String setDriver(String driver);
	
	/**
	 * 搭载货物
	 * @param goods
	 * @throws NullPointerException
	 * @throws IllegalArgumentException
	 */
	public void loadGoods(String goods)throws NullPointerException,IllegalArgumentException;
}


package com.fruitking.proxy;

/**
 * 汽车服务类接口实现
 * @author fruitking
 * @since 2010-02-23
 */
public class CarServiceImpl implements CarService{
	
	/**
	 * 启动汽车
	 */
	public void start(){
		System.out.println("start my car...");
	}
	
	/**
	 * 获得汽车搭载人数
	 * @return
	 */
	public int getLoadAmount(){
		System.out.println("count the person amount in my car...");
		return 5;
	}
	
	/**
	 * 设置驾驶员
	 * @param driver
	 * @return
	 */
	public String setDriver(String driver){
		System.out.println("driver is:"+driver);
		if(driver==null||"".equals(driver)){
			return "There is not driver.";
		}else{
			return "The driver's name is " + driver + ".";
		}
	}
	
	/**
	 * 搭载货物
	 * @param goods
	 * @throws NullPointerException
	 * @throws IllegalArgumentException
	 */
	public void loadGoods(String goods)throws NullPointerException,IllegalArgumentException{
		if(goods==null||"".equals(goods)){
			throw new NullPointerException("The argument goods is null.");
		}else if("tiger".equals(goods)){
			throw new IllegalArgumentException("The argument goods is invalid.");
		}
		System.out.println("load goods is:"+goods);
	}
}

先来看看代理模式,定义一个代理类,然后调用代理类
package com.fruitking.proxy.pattern;

import com.fruitking.proxy.CarService;

/**
 * 汽车服务类接口的代理类实现
 * @author fruitking
 * @since 2010-02-23
 */
public class CarServiceProxy implements CarService {
	
	private CarService carServiceTarget;//被代理的目标类
	
	/**
	 * 在构造函数中设置被代理的目标类
	 * 也可以使用set方法设置被代理的目标类
	 * @param carServiceTarget
	 */
	public CarServiceProxy(CarService carServiceTarget){
		this.carServiceTarget = carServiceTarget;
	}

	/**
	 * 启动汽车
	 */
	public void start(){
		System.out.println("before excute target object...");
		carServiceTarget.start();
		System.out.println("after excute target object...");
	}
	
	/**
	 * 获得汽车搭载人数
	 * @return
	 */
	public int getLoadAmount(){
		System.out.println("before excute target object...");
		int amount = carServiceTarget.getLoadAmount();
		System.out.println("after excute target object...");
		return amount;
	}
	
	/**
	 * 设置驾驶员
	 * @param driver
	 * @return
	 */
	public String setDriver(String driver){
		System.out.println("before excute target object...");
		String resultObject = carServiceTarget.setDriver(driver);
		System.out.println("after excute target object...");
		return resultObject;
	}
	
	/**
	 * 搭载货物
	 * @param goods
	 * @throws NullPointerException
	 * @throws IllegalArgumentException
	 */
	public void loadGoods(String goods)throws NullPointerException,IllegalArgumentException{
		//这里不实现任何操作
	}
}


package com.fruitking.proxy.pattern;

import com.fruitking.proxy.CarService;
import com.fruitking.proxy.CarServiceImpl;

public class TestProxyPattern {

	/**
	 * 代理模式中的调用
	 * @param args
	 */
	public static void main(String[] args) {
		CarService carServiceTarget = new CarServiceImpl();
		CarServiceProxy carServiceProxy = new CarServiceProxy(carServiceTarget);
		//执行代理类的方法
		//作用一:间接执行被代理类的方法,
		//作用二:代理类可以在被代理类方法执行前后做一些额外操作
		//总结:不更改原有类的功能和程序代码情况下,实现额外的功能能
		//缺点:要为每个被代理类编写一个代理类,且需要实现相同接口的所有方法
		carServiceProxy.start();
		carServiceProxy.getLoadAmount();
		String driver = carServiceProxy.setDriver("fruitking");
		System.out.println(driver);
	}
}



再来看看JDK动态代理
package com.fruitking.proxy.jdkdproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

import com.fruitking.proxy.CarService;

/**
 * java动态代理实现类
 * @author fruitking
 * @since 2010-02-23
 */
public class CarServiceJDKDynamicProxy implements InvocationHandler {

	private CarService carServiceTarget;//被代理的目标类
	
	/**
	 * 在构造函数中设置被代理的目标类
	 * 也可以使用set方法设置被代理的目标类
	 * @param carServiceTarget
	 */
	public CarServiceJDKDynamicProxy(CarService carServiceTarget){
		this.carServiceTarget = carServiceTarget;
	}
	
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("before excute target object...");
		Object object = method.invoke(this.carServiceTarget,args);
		System.out.println("after excute target object...");
		return object;
	}
}


package com.fruitking.proxy.jdkdproxy;

import java.lang.reflect.Proxy;

import com.fruitking.proxy.CarService;
import com.fruitking.proxy.CarServiceImpl;

public class TestJDKDynamicProxy {

	/**
	 * JDK中动态代理技术中的代理调用
	 * @param args
	 */
	public static void main(String[] args) {
		CarService carServiceTarget = new CarServiceImpl();
		CarServiceJDKDynamicProxy carServiceJDKDynamicProxyTarget = new CarServiceJDKDynamicProxy(carServiceTarget);
		CarService carServiceProxy = (CarService)Proxy.newProxyInstance(carServiceTarget.getClass().getClassLoader(),new Class[]{CarService.class}, carServiceJDKDynamicProxyTarget);
		//执行代理类的方法
		//作用一:间接执行被代理类的方法,
		//作用二:代理类可以在被代理类方法执行前后做一些额外操作
		//总结:不更改原有类的功能和程序代码情况下,实现额外的功能能
		//缺点:要为每个被代理类编写一个代理类,且具有相同的接口
		carServiceProxy.start();
		carServiceProxy.getLoadAmount();
		String driver = carServiceProxy.setDriver("fruitking");
		System.out.println(driver);
	}

}


最后来看看spring的AOP机制的实现
package com.fruitking.proxy.springaop;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

/**
 * 使用spring的AOP机制的事前通知接口实现
 * @author fruitking
 * @since 2010-02-23
 */
public class CarServiceBeforeAdvice implements MethodBeforeAdvice{
	
	public void before(Method method, Object[] args, Object target)throws Throwable {
		System.out.println("before excute target object...");
		String methodName = method.getName();  //得到方法名 
		String targetClassName = target.getClass().getName();//得到调用类名
		System.out.println(targetClassName+"."+methodName+"()");
	}
}

package com.fruitking.proxy.springaop;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

/**
 * 使用spring的AOP机制的事前通知接口实现
 * @author fruitking
 * @since 2010-02-23
 */
public class CarServiceAfterAdvice implements AfterReturningAdvice {

	public void afterReturning(Object returnValue,Method method,Object[] args,Object target)throws Throwable{
		String methodName = method.getName();  //得到方法名 
		String targetClassName = target.getClass().getName();//得到调用类名
		System.out.println(targetClassName+"."+methodName+"()");
		System.out.println("after excute target object...");
	}
}

package com.fruitking.proxy.springaop;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

/**
 * 使用spring的AOP机制的事前通知接口实现
 * @author fruitking
 * @since 2010-02-23
 */
public class CarServiceAroundAdvice implements MethodInterceptor {
	
	public Object invoke(MethodInvocation invocation) throws Throwable {
		System.out.println("before around excute target object...");
		String methodName = invocation.getMethod().getName();  //得到方法名 
		String targetClassName = invocation.getClass().getName();//得到调用类名
		System.out.println(targetClassName+"."+methodName+"()");
		Object result = invocation.proceed(); //调用横切点,即真实操作
		System.out.println("after around excute target object...");
		return result;
	}
}

package com.fruitking.proxy.springaop;

import org.springframework.aop.ThrowsAdvice;

/**
 * 使用spring的AOP机制的事前通知接口实现
 * @author fruitking
 * @since 2010-02-23
 */
public class CarServiceThrowsAdvice implements ThrowsAdvice {
	
	public void afterThrowing(NullPointerException e){//可以定义多个方法,只要传入的参数是不同异常
		System.out.print("not load anything goods!");
	}
	
	public void afterThrowing(IllegalArgumentException e){//可以定义多个方法,只要传入的参数是不同异常
		System.out.print("load a tiger,it's very much dangerous!");
	}

}

spring的配置文件,把这些使用IOC处理
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
	
	<bean id="carServiceTarget" class="com.fruitking.proxy.CarServiceImpl"/>
	 
	<bean id="carServiceBeforeAdvice" class="com.fruitking.proxy.springaop.CarServiceBeforeAdvice"/>
	
	<bean id="carServiceAfterAdvice" class="com.fruitking.proxy.springaop.CarServiceAfterAdvice"/>
	
	<bean id="carServiceAroundAdvice" class="com.fruitking.proxy.springaop.CarServiceAroundAdvice"/>
	
	<bean id="carServiceThrowsAdvice" class="com.fruitking.proxy.springaop.CarServiceThrowsAdvice"/>
    
    <bean id="carService" class="org.springframework.aop.framework.ProxyFactoryBean"> 
        <property name="proxyInterfaces" value="com.fruitking.proxy.CarService"/> 
        <property name="target" ref="carServiceTarget"/> 
        <property name="interceptorNames"> 
            <list> 
                <value>carServiceBeforeAdvice</value>
                <value>carServiceAfterAdvice</value>
                <value>carServiceAroundAdvice</value>
                <value>carServiceThrowsAdvice</value>
            </list> 
        </property>
    </bean>
    
</beans>

package com.fruitking.proxy.springaop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.fruitking.proxy.CarService;

public class TestSpringAOP {

	/**
	 * 利用spring的AOP机制实现“代理”的横向抽取机制方式
	 * @param args
	 */
	public static void main(String[] args) {
		ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml"); 
		CarService carService = (CarService) ctx.getBean("carService");
		carService.start();
		carService.getLoadAmount();
		String driver = carService.setDriver("fruitking");
		System.out.println(driver);
		System.out.println("------------------------------");
		carService.loadGoods("Miss Mary");
		System.out.println("------------------------------");
		try{
			carService.loadGoods(null);
		}catch(NullPointerException e){
			e.printStackTrace();
		}
		System.out.println("------------------------------");
		try{
			carService.loadGoods("tiger");
		}catch(IllegalArgumentException e){
			e.printStackTrace();
		}
	}

}

分享到:
评论
3 楼 laoma102 2014-10-17  
顶个,谢楼主
2 楼 sweed0 2013-04-10  
1 楼 fruitking 2010-02-24  
示例代码可以下载,另外需要引入spring.jar和commons-logging.jar包
我这里就没有上传了

相关推荐

    JDK动态代理 spring aop 的原理

    现在让我们深入探讨JDK动态代理和Spring AOP的原理。 首先,JDK动态代理基于Java的反射机制,通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类用于创建一个代理对象,...

    从JDK动态代理到spring AOP

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

    spring之AOP(动态代理)

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

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

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

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

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

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

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

    Spring-AOP-JDK动态代理

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

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

    Spring 框架中 JDK 动态代理和 CGLIB 动态代理是 Spring AOP 中一个非常重要的知识点。Spring AOP 框架会根据实际情况选择使用 JDK 的动态代理还是 CGLIB 的动态代理。 JDK 动态代理是 Java 自带的动态代理机制,它...

    Java动态代理(Spring Aop原理)

    Spring AOP提供了两种代理方式:JDK动态代理和CGLIB代理。JDK动态代理用于目标对象实现接口的情况,而CGLIB代理则用于目标对象没有实现接口的情况。Spring默认使用JDK动态代理,但如果目标对象没有实现接口,它会...

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

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

    代理模式(Proxy Pattern) 1. 概述 1.1 基本概念 1.2 为什么需要代理模式 1.3 代理模式的四个角色 2. 代理模式的类型 2.1 静态代理 2.2 JDK动态代理

    5. 代理模式在Spring AOP中的应用 5.1 Spring AOP的代理机制 5.2 Spring AOP示例 5.3 Spring AOP代理原理分析 6. 代理模式与其他设计模式的区别与联系 6.1 代理模式 vs 装饰器模式 示例对比: 6.2 代理模式 vs ...

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

    本文将深入探讨Spring是如何通过JDK的动态代理来实现AOP的。 首先,我们要理解JDK动态代理的基本原理。在Java中,动态代理主要由`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口组成。...

    springAop默认代理方式.zip

    2. **动态代理**:Spring AOP 的默认代理方式是动态代理,它包括JDK动态代理和CGLIB代理。当目标对象实现了至少一个接口时,Spring将使用JDK的动态代理机制。JDK动态代理通过实现InvocationHandler接口,并在运行时...

    springAOP配置动态代理实现

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

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

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

    代理模式(含动态代理讲解)【Spring AOP实质】

    对于JDK动态代理,Spring会创建一个实现了目标类所有接口的代理类,这个代理类在调用目标方法时会插入AOP的切面逻辑,如事务处理、日志记录等。CGLIB则是通过继承目标类的方式创建代理对象,如果目标类没有定义接口...

    SpringAOP之探秘(动态代理、责任链模式、注解使用)

    本篇文章将深入探讨Spring AOP中的动态代理、责任链模式以及注解的使用。 首先,动态代理是实现AOP的关键技术之一。在Java中,有两种主要的动态代理实现方式:JDK动态代理和CGLIB。JDK动态代理基于接口,当目标类...

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

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

    spring jdk动态代理

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

Global site tag (gtag.js) - Google Analytics