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

(原)Java动态代理实现(简单AOP实现)

阅读更多
本文介绍了简单Aop实现的方法,意在抛砖引玉。

首先是简单的Aspect接口
package org.aspect;

/**
 * 切面接口
 */
public interface Aspect {
	
	/**
	 * 事先执行
	 */
	public void doBefore();
	
	/**
	 * 事后执行
	 */
	public void doAfter();
}


然后是代理工厂
package org.aspect;

import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

/**
 * 代理工厂类
 */
public class DynamicProxyFactory {
	
	/**
	 * 私有构造方法
	 */
	private DynamicProxyFactory() {}
	
	/**
	 * 工厂方法
	 * 
	 * @param instance 代理目标类实例对象
	 * @param aspect 切面对象
	 */
	public static Object newInstance(Object instance, Aspect aspect) {
		
		List<Aspect> aspectList = new ArrayList<Aspect>();
		aspectList.add(aspect);
		
		return newInstance(instance, aspectList);
	}
	
	/**
	 * 工厂方法
	 * 
	 * @param instance 代理目标类实例对象
	 * @param aspectList 切面集合
	 */
	public static Object newInstance(Object instance, List<Aspect> aspectList) {
		SimpleInvocationHandler hander = new SimpleInvocationHandler();
		hander.setAspectList(aspectList);
		hander.setSource(instance);
		return Proxy.newProxyInstance(instance.getClass().getClassLoader(), 
									  instance.getClass().getInterfaces(), 
									  hander);
	}
}


最后是代理执行类
package org.aspect;

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

/**
 * 代理委托接口实现
 */
public class SimpleInvocationHandler implements InvocationHandler {

	
	private Object source = null;
	
	private List<Aspect> aspectList = null;
	
	
	public Object getSource() {
		return source;
	}


	public void setSource(Object source) {
		this.source = source;
	}


	public List<Aspect> getAspectList() {
		return aspectList;
	}


	public void setAspectList(List<Aspect> aspectList) {
		this.aspectList = aspectList;
	}

	/**
	 * 委托方法
	 * 
	 * @param proxy 代理对象
	 * @param method 代理方法
	 * @param args 方法参数
	 */
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		
		for (Aspect aspect : aspectList) {
			aspect.doBefore();
		}
		
		Object retObj = method.invoke(getSource(), args);
		
		for (int index = aspectList.size() - 1; index >= 0; index--) {
			aspectList.get(index).doAfter();
		}
		
		return retObj;
	}
	
}


测试代码

public interface Student {
	public void sayHello();
}

import org.aspect.Aspect;

public class StudentAspectOne implements Aspect {

	@Override
	public void doAfter() {
		System.out.println("do After One");
		
	}

	@Override
	public void doBefore() {
		System.out.println("do Before One");
		
	}

}

import org.aspect.Aspect;


public class StudentAspectTwo implements Aspect{
	@Override
	public void doAfter() {
		System.out.println("do After Two");
		
	}

	@Override
	public void doBefore() {
		System.out.println("do Before Two");
		
	}
}

public class StudentImpl implements Student {

	@Override
	public void sayHello() {
		System.out.println("Student");
	}

}

import java.util.ArrayList;
import java.util.List;

import org.aspect.Aspect;
import org.aspect.DynamicProxyFactory;

public class Test {

	public static void main(String[] args) {
		
		List<Aspect> aspectList = new ArrayList<Aspect>();
		
		aspectList.add(new StudentAspectOne());
		aspectList.add(new StudentAspectTwo());
		Student s = (Student)DynamicProxyFactory.newInstance(new StudentImpl(), aspectList);
		s.sayHello();
	}

}



执行Test,控制台返回

do Before One
do Before Two
Student
do After Two
do After One
分享到:
评论
2 楼 rainsilence 2010-09-23  
这个
zxlsky1314 写道
学习了~~~

这些只是最简单的啦。可以对第一个接口进行扩展
1 楼 zxlsky1314 2010-09-21  
学习了~~~

相关推荐

    Java Web程序设计教程

    12.1.3java动态代理与aop 244 12.1.4springaop简介 245 12.2使用spring的通知 246 12.2.1beforeadvice 246 12.2.2afterreturningadvice 248 12.2.3methodinterceptor 249 12.2.4throwadvice 250 12.3使用...

    架构探险 原书源码

    为了使框架具备 AOP 特性,从代理技术讲到 AOP 技术,从 ThreadLocal 技术讲到事务控制技术。最后对框架进行优化与扩展,通过对现有框架的优化,使其可以提供更加完备的功能,并以扩展 Web 服务插件与安全控制插件为...

    simple-framework:基于Servlet的轻量级JavaWeb框架的实现

    Simple-Framework使用文档​Simple-Framework是一种轻量级Java Web框架,可基于此框架进行...​实现过程中使用到的技术有:Tomcat、Servlet 、JDBC、数据库、反射、CGLIB动态代理、设计模式(模板模式、责任链模式)、Thr

    broccoli:模仿实现注解式springMVC

    1.通过动态代理实现注解方式的spring AOP,以及简单的IOC 支持Jdk原生代理和Cglib代理 支持多个代理的叠加效果 通过spi实现代理的扩展 目前实现了Before,After,Aroud 三种通知方式. 2.基于netty实现http连接,接受get,...

    基于maven项目的SSM框架与layu前端框架的代码

    实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织...

    Spring 2.0 开发参考手册

    2.3.1. 更加简单的AOP XML配置 2.3.2. 对@AspectJ 切面的支持 2.4. 中间层 2.4.1. 在XML里更为简单的声明性事务配置 2.4.2. JPA 2.4.3. 异步的JMS 2.4.4. JDBC 2.5. Web层 2.5.1. Spring MVC的表单标签库 ...

    Spring中文帮助文档

    2.3.1. 更加简单的AOP XML配置 2.3.2. 对@AspectJ 切面的支持 2.3.3. 对bean命名pointcut( bean name pointcut element)的支持 2.3.4. 对AspectJ装载时织入(AspectJ load-time weaving)的支持 2.4. 中间层 ...

    Spring API

    2.3.1. 更加简单的AOP XML配置 2.3.2. 对@AspectJ 切面的支持 2.3.3. 对bean命名pointcut( bean name pointcut element)的支持 2.3.4. 对AspectJ装载时织入(AspectJ load-time weaving)的支持 2.4. 中间层 ...

    Spring-Reference_zh_CN(Spring中文参考手册)

    2.3.1. 更加简单的AOP XML配置 2.3.2. 对@AspectJ 切面的支持 2.4. 中间层 2.4.1. 在XML里更为简单的声明性事务配置 2.4.2. JPA 2.4.3. 异步的JMS 2.4.4. JDBC 2.5. Web层 2.5.1. Spring MVC的表单标签库 2.5.2. ...

    spring chm文档

    2.3.1. 更加简单的AOP XML配置 2.3.2. 对@AspectJ 切面的支持 2.4. 中间层 2.4.1. 在XML里更为简单的声明性事务配置 2.4.2. JPA 2.4.3. 异步的JMS 2.4.4. JDBC 2.5. Web层 2.5.1. Spring MVC的表单标签库 ...

    Spring.3.x企业应用开发实战(完整版).part2

    6.2.3 CGLib动态代理 6.2.4 AOP联盟 6.2.5 代理知识小结 6.3 创建增强类 6.3.1 增强类型 6.3.2 前置增强 6.3.3 后置增强 6.3.4 环绕增强 6.3.5 异常抛出增强 6.3.6 引介增强 6.4 创建切面 6.4.1 切点类型 6.4.2 切面...

    Spring3.x企业应用开发实战(完整版) part1

    6.2.3 CGLib动态代理 6.2.4 AOP联盟 6.2.5 代理知识小结 6.3 创建增强类 6.3.1 增强类型 6.3.2 前置增强 6.3.3 后置增强 6.3.4 环绕增强 6.3.5 异常抛出增强 6.3.6 引介增强 6.4 创建切面 6.4.1 切点类型 6.4.2 切面...

    asp.net知识库

    自定义通用System.Web.UI.IHierarchicalDataSource简单实现 在 ASP.NET 2.0 中创建 Web 应用程序主题 ASP.NET 2.0 中的数据访问 ASP.NET 2.0:弃用 DataGrid 吧,有新的网格控件了! 将 ASP.NET 2.0 应用程序服务...

    ssh(structs,spring,hibernate)框架中的上传下载

    系统Web层将来切换到另一种实现技术的可能性也微乎其微,所以笔者觉得没有必要为了这个业务层完全独立于调用层的过高目标而去搞一个额外的隔离层,浪费了原材料不说,还将系统搞得过于复杂,相比于其它原则,"简单...

Global site tag (gtag.js) - Google Analytics