关闭

Java-----------类似spring的AOP框架的实现

标签: springaop框架objectbeanproperties
146人阅读 评论(0) 收藏 举报

android培训java培训、期待与您交流!

        这个是在上一个视频的基础上来进行是实现的。首先就是有一个BeanFactory来进行总的整合,在这个类里面有个方法getBean参数就是传入的name,该名称在属性文件中有标记。这个方法返回一个bean或者一个代理的实例对象。

package springFrame;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import test.Advice;

public class BeanFactory {
	Properties pro = new Properties();
	public  BeanFactory(InputStream ips){
		try {
			pro.load(ips);//加载属性文件
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public Object getBean(String name){
		//获得这个是目标bean还是代理bean
		String className = pro.getProperty(name);
		//从属性文件中得到名字是name对应的名称
		Object bean = null;
				
		try {
			Class clazz = Class.forName(className);
			//通过这个名称获得该名称对应的类的字节码
			bean = clazz.newInstance();
			//该类进行实例化
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} 
			
		if(bean instanceof ProxyFactoryBean){
			//如果这个bean是代理类
			ProxyFactoryBean proxyFactoryBean = (ProxyFactoryBean)bean;
			//转化为这个代理的bean
			Advice advice = null;
			Object target = null;
			try {
				advice = (Advice)Class.forName(pro.getProperty(name + ".advice")).newInstance();
				//契约实例化通过属性文件得到的名称
				target  = Class.forName(pro.getProperty(name + ".target")).newInstance();
				//目标的实例化通过属性文件中得到的名称
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
			proxyFactoryBean.setTarget(target);
			//把这个目标类设置到代理类的bean中
			proxyFactoryBean.setAdvice(advice);
			//把契约类设置到代理类的bean中
			Object proxy = proxyFactoryBean.getProxy();
			//通过代理类的bean来获得这个代理的类的实例对象并返回
			return proxy;
		}
			
		return bean;
	}
}
上面的代码是BeanFactory,通过它就可以得到我们想要的是bean还是代理。

package springFrame;

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

import test.Advice;

public class ProxyFactoryBean {
	
	private Object target;//定义目标类
	private Advice advice;//定义契约
	
	public Object getProxy(){
		Object proxy3 = Proxy.newProxyInstance(//实例化一个代理
				target.getClass().getClassLoader(), //传入目标的加载器
				target.getClass().getInterfaces(), //传入目标的接口
				
				new InvocationHandler(){
					
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {
						advice.beforeMethod(method);//执行契约类的的before方法
						Object revalue = method.invoke(target, args);
						advice.afterMethod(method);//执行契约类的after方法
						return revalue;//返回给代理
					}
				});
		return proxy3;//返回一个代理
	}
	public Object getTarget() {//获得目标
		return target;
	}
	public void setTarget(Object target) {//设置目标
		this.target = target;
	}
	public Advice getAdvice() {//获得契约
		return advice;
	}
	public void setAdvice(Advice advice) {//设置契约
		this.advice = advice;
	}
}

       这个是代理类的生成工厂,在这个类里面我们要有两个传入的参数,才能正确的生成目标类的代理,一个是目标另外就是契约。契约是上次笔记中就有,主要是我们要加入的系统功能的实现。

然后就是测试:

package springFrame;

import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;

public class AopFrameworkTest {

	public static void main(String[] args) throws Exception,
			IllegalAccessException {

		InputStream ips = AopFrameworkTest.class
				.getResourceAsStream("config.properties");
		Object bean = new BeanFactory(ips).getBean("xxx");
		Collection c = (Collection)bean;//由于这个是代理,所以要通过接口Collection来获得
		c.add("1");
		c.size();
		System.out.println(bean.getClass().getName());
		}
}
最后测试的结果很正常,输出了这个代理类的名称和执行add的时候会把我们契约中要加入的功能也已经加入了进去。


android培训java培训、期待与您交流!

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:3586次
    • 积分:128
    • 等级:
    • 排名:千里之外
    • 原创:10篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章存档