`

代理模式,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`...

    从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动态代理技术来实现这一功能,并通过实例解析其底层实现。 首先,...

    Spring AOP 16道面试题及答案.docx

    Spring提供了两种代理方式:JDK动态代理和CGLIB代理。JDK代理适用于那些实现了接口的类,而CGLIB代理则适用于没有实现接口的类。 引介(Introduction)是Spring AOP的一个特性,允许在通知对象中声明并实现它们原本...

Global site tag (gtag.js) - Google Analytics