`

java ioc,aop实现(内省),仿spring功能实现.

阅读更多
通过创建InvocationHandler代理类及java bean内省方法及读取配置文件,实现spring核心功能IOC及AOP功能.
先看测试类及结果,全代码已上传文件供下载.
测试类
package test;

import core.AOPFactory;

public class TestAOP {
	public static void main(String[] args) {
		IPerson son = (IPerson) AOPFactory.getBean("class.son");
		son.sayHello();

		IPerson son2 = (IPerson) AOPFactory.getBean("class.son");
		System.out.println("class.son是否为单例:" + (son2 == son));

		System.out.println("---------------------------------------------------------");

		IPerson father = (IPerson) AOPFactory.getBean("class.father");
		father.sayHello();
		System.out.println(son == father.getSon());

		IPerson father2 = (IPerson) AOPFactory.getBean("class.father");
		System.out.println("class.father是否为单例:" + (father2 == father));
	}
}

运行结果输出:
AOP前test.Person.sayHello
执行sayhello方法:[name=xiaoma,age=1,work=student,son=null]
AOP后test.Person.sayHello
class.son是否为单例:true
---------------------------------------------------------
error:test方法找不到
AOP前test.Person.sayHello
执行sayhello方法:[name=xieetianya,age=28,work=javaer,son=[name=xiaoma,age=1,work=student,son=null]]
AOP后test.Person.sayHello
true
error:test方法找不到
class.father是否为单例:false


其他文件:
sysconfig.properties
# 无.号结尾表示单例
class.son=test.Person
class.son.name=java.lang.String-xiaoma
class.son.age=int-1
class.son.work=java.lang.String-student

# .号结尾非单例
class.father=test.Person.
class.father.name=java.lang.String-xieetianya
class.father.age=int-28
class.father.work=java.lang.String-javaer
# 有意写个错的测试
class.father.test=java.lang.String-haha
#ref表示引用
class.father.son=ref-class.son

IPerson.java
package test;

public interface IPerson {
	void sayHello();

	int getAge();

	void setAge(int age);

	String getName();

	void setName(String name);

	String getWork();

	void setWork(String work);

	IPerson getSon();

	void setSon(IPerson son);

	String toString();
}

Person.java
package test;

public class Person implements IPerson {
	private String name;
	private int age;
	private String work;
	private IPerson son;

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getWork() {
		return work;
	}

	public void setWork(String work) {
		this.work = work;
	}

	public IPerson getSon() {
		return son;
	}

	public void setSon(IPerson son) {
		this.son = son;
	}

	public void sayHello() {
		System.out.println("执行sayhello方法:" + this);
	}

	public String toString() {
		return "[name=" + name + ",age=" + age + ",work=" + work + ",son=" + son + "]";
	}
}

主要文件

AOPFactory.java
package core;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

/**
 * 
 * AOP工厂类 IOC
 * 
 * @author QQ:814560828
 * @date Jul 4, 2012
 */
public class AOPFactory {
	private static Map<String, Object> map = new Hashtable<String, Object>();

	/**
	 * 取代理实例
	 * 
	 * @param name
	 *            在sysconfig.properties配置的变量(类名)
	 * @return
	 */
	public static Object getBean(String name) {
		String clzName = ParamsUtil.get(name);
		// 判断是否为单例
		boolean isSingle = !clzName.endsWith(".");
		if (!isSingle) {
			clzName = clzName.substring(0, clzName.length() - 1);
		}
		// 单例存在返回结束
		if (isSingle && AOPFactory.map.containsKey(name)) {
			return AOPFactory.map.get(name);
		}
		// 单例初始化或非单位初始化
		Object result = null;
		AOPProxy proxy = new AOPProxy();
		Object obj = getClassInstance(clzName);
		// bean设置
		if (obj != null) {
			result = proxy.bind(obj);
			invoke(obj, name);
		}
		// 单例
		if (isSingle) {
			AOPFactory.map.put(name, result);
		}
		return result;
	}

	/**
	 * 反射生成对象
	 * 
	 * @param clzName
	 * @return
	 */
	private static Object getClassInstance(String clzName) {
		Object obj = null;
		try {
			Class<?> clz = Class.forName(clzName);
			obj = (Object) clz.newInstance();
		} catch (ClassNotFoundException cnfe) {
			System.out.println("ClassNotFoundException:" + cnfe.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return obj;
	}

	/**
	 * 执行赋值
	 * 
	 * @param obj
	 * @param name
	 */
	private static void invoke(Object obj, String name) {
		List<AOPParam> list = ParamsUtil.getList(name);
		if (list != null && list.size() != 0) {
			for (AOPParam param : list) {
				// java bean 内省赋值
				PropertyDescriptor pd = null;
				String method = param.getName();
				try {
					pd = new PropertyDescriptor(method, obj.getClass());
				} catch (IntrospectionException e) {
					System.out.println("error:" + method + "设置方法找不到");
				}
				if (pd != null) {
					Method writeMethod = pd.getWriteMethod();
					try {
						writeMethod.invoke(obj, param.getValue());
					} catch (IllegalAccessException e) {
						System.out.println("error:" + method + "设置实例出错");
					} catch (IllegalArgumentException e) {
						System.out.println("error:" + method + "设置参数类型不对");
					} catch (InvocationTargetException e) {
						System.out.println("error:" + method + "设置方法执行出错");
					}
				}
				// 内省 读属性
				// Method readMethod = pd.getReadMethod();
				// Object str = readMethod.invoke(obj);
				// System.out.println(str);

			}
		}
	}
}

AOPMethod.java
package core;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 
 * AOP配置 待优化
 * 
 * @author QQ:814560828
 * @date Jul 4, 2012
 */
public class AOPMethod {
	/**
	 * 判断是否需要执行aop
	 * 
	 * @param obj
	 *            执行的实例
	 * @param method
	 *            将要执行的方法名
	 * @return
	 */
	public static boolean check(Object obj, String method) {
		// 这里简单展示设置方法含有say的执行aop
		Pattern p = Pattern.compile("say");
		Matcher m = p.matcher(method);
		if (m.find()) {
			return true;
		}
		return false;
	}

	/**
	 * 方法前执行
	 * 
	 * @param obj
	 * @param method
	 */
	public static void before(Object obj, String method) {
		System.out.println("AOP前" + obj.getClass().getName() + "." + method);
	}

	/**
	 * 方法后执行
	 * 
	 * @param obj
	 * @param method
	 */
	public static void after(Object obj, String method) {
		System.out.println("AOP后" + obj.getClass().getName() + "." + method);
	}
}

AOPParam.java
package core;

/**
 * 
 * AOP参数
 * 
 * @author QQ:814560828
 * @date Jul 4, 2012
 */
public class AOPParam {
	private String name;// 名字
	private String type;// 类型
	private Object value;// 值

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public Object getValue() {
		return value;
	}

	/**
	 * 待优化
	 * 
	 * @param value
	 */
	public void setValue(Object value) {
		if ("int".equals(type) || "java.lang.Integer".equals(type)) {
			this.value = Integer.parseInt((String) value);
		} else if ("short".equals(type) || "java.lang.Short".equals(type)) {
			this.value = Short.parseShort((String) value);
		} else if ("long".equals(type) || "java.lang.Long".equals(type)) {
			this.value = Long.parseLong((String) value);
		} else if ("float".equals(type) || "java.lang.Float".equals(type)) {
			this.value = Float.parseFloat((String) value);
		} else if ("double".equals(type) || "java.lang.Double".equals(type)) {
			this.value = Double.parseDouble((String) value);
		} else if ("java.lang.String".equals(type)) {
			this.value = value;
		} else if ("ref".equals(type)) {
			type = ParamsUtil.get((String) value);
			this.value = AOPFactory.getBean((String) value);
		} else {
			this.value = value;
		}
	}

	public String toString() {
		return "name=" + name + ",value=" + value + ",type=" + type;
	}
}

AOPProxy.java
package core;

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

/**
 * 
 * AOP执行类
 * 
 * @author QQ:814560828
 * @date Jul 4, 2012
 */
public class AOPProxy implements InvocationHandler {
	private Object proxyObj;

	/**
	 * 绑定类
	 * 
	 * @param obj
	 * @return
	 */
	public Object bind(Object obj) {
		this.proxyObj = obj;
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
	}

	/**
	 * 执行方法
	 */
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object result = null;
		// 方法执行前
		if (AOPMethod.check(proxyObj, method.getName())) {
			AOPMethod.before(proxyObj, method.getName());
		}
		try {
			result = method.invoke(proxyObj, args); // 原方法
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 方法执行后
		if (AOPMethod.check(proxyObj, method.getName())) {
			AOPMethod.after(proxyObj, method.getName());
		}
		return result;
	}
}

ParamsUtil.java
package core;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Set;

/**
 * 
 * 读取sysconfig.properties参数
 * 
 * @author QQ:814560828
 * @date Jul 4, 2012
 */
public class ParamsUtil {
	private static Properties p = new Properties();
	static {
		init();
	}

	public static void init() {
		try {
			p.load(ParamsUtil.class.getResourceAsStream("/test/sysconfig.properties"));
		} catch (IOException e) {
			System.out.println("加载文件出错/test/sysconfig.properties");
		}
	}

	public static String get(String key) {
		return get(key, "");
	}

	/**
	 * 取属性值
	 * 
	 * @param key
	 * @param defaultValue
	 * @return
	 */
	public static String get(String key, String defaultValue) {
		String value = p.getProperty(key);
		if (value == null || value.equals(""))
			return defaultValue;
		return value;
	}

	/**
	 * 取key+"."开头的所有参数列表
	 * 
	 * @param key
	 * @return
	 */
	public static List<AOPParam> getList(String key) {
		List<AOPParam> list = new ArrayList<AOPParam>();
		Set<Object> set = p.keySet();
		String tempKey;// 原始key
		int tempSplite;// -号索引
		String tempValue;// -号后值:类型及值
		int tempDotIndex;// .号索引
		AOPParam param;

		for (Object value : set) {
			tempKey = (String) value;
			if (tempKey.startsWith(key + ".")) {
				tempDotIndex = (key + ".").length();
				tempValue = get(tempKey);
				tempSplite = tempValue.indexOf("-");
				param = new AOPParam();
				param.setName(tempKey.substring(tempDotIndex));
				param.setType(tempValue.substring(0, tempSplite));
				param.setValue(tempValue.substring(tempSplite + 1));
				list.add(param);
			}
		}
		return list;
	};

}


分享到:
评论

相关推荐

    用反射和内省技术实现简单SpringIOC

    本篇文章将深入探讨如何利用反射和内省技术来实现一个简单的Spring IOC。首先,我们来理解什么是反射和内省。 反射是Java提供的一种强大的动态类型机制,它允许程序在运行时检查类的信息,如类名、属性、方法等,并...

    2022年品味Spring 的魅力Java教程.docx

    Spring框架是Java开发中不可或缺的一部分,以其非侵入式的设计理念和强大的功能赢得了广大开发者喜爱。本教程将深入探讨Spring的魅力,特别是在2022年这个时间点,Spring的影响力和重要性更加凸显。 Spring的核心...

    spring学习笔记 私塾在线

    Spring Expression Language (SpEL)是Spring框架中强大的内省和表达式评估工具。它允许在运行时查询和操作对象图。本章将解释如何使用SpEL进行条件判断、属性访问、算术运算以及调用方法等,是增强应用程序灵活性和...

    java常用第三方软件包大全_.docx

    12. **CGLib**:一个动态代理框架,常用于Spring和Hibernate中的AOP实现。 13. **Super CSV**:用于CSV文件的读写,提供了强大的功能和灵活性。 14. **com4j**:允许Java调用COM组件,用于与Windows平台的交互。 ...

    大数据分析培训机构学习路线.docx

    掌握 Java 语言的高级特性、Java 线程池技术、Web 开发技术、 Struts2、Hibernate、Spring 等框架的使用,了解软件分层思想、AJAX 实现异步刷新、过滤器、监听器、文件上传、下载在线支付功能实现等知识点,并且能够...

    大数据分析培训机构学习路线.pdf

    Spring框架的IOC、DI、AOP和数据库编程也会被深入讲解,以提高学员的框架应用能力。 在项目实践中,学员将参与“易买网”和“国际物流”两个项目。在“易买网”项目中,会接触前端开发技术和JAVAWEB的高级知识,...

    华为校园招聘历年经典面试题汇总:C++研发岗1

    IOC使得对象的创建和依赖关系的管理由Spring容器负责,而AOP则允许开发者在不修改原有代码的情况下,通过切面来添加新的功能或行为。 2. **数据库索引的底层实现**: 数据库索引通常基于不同的数据结构实现,如B树...

Global site tag (gtag.js) - Google Analytics