<黑马程序员>代理模式总结-仿制简单spring框架

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

接上两篇技术文档,对代理模式的最后总结,建议spring框架开发,那么模拟一个需求如下:

 * 需求:以动态代理和反射方式实现Spring中AOP面向切面编程思想
 * 在config.properties配置文件中进行配置,实现程序读取哪些类进行运行
 * 比如,读取的xxx是com.proxy.aopframework.DynamicProxy,则以代理类执行,并且如果是代理类执行,
 * 则会读取active和target,target为委托类,active为日志类,如果配置AdviceAfter,
 * 则在委托类执行后记录日志,否则在之前记录日志.

config,peroperties文件如下:

xxx=com.proxy.aopframework.DynamicProxy
#xxx=java.util.ArrayList
xxx.active=com.proxy.aopframework.AdviceAfter
xxx.target=java.util.ArrayList


 * 思路:
 * 
 * 1、将config.properties读进来,根据读进来的ID和值,使用Properties类进行load存储
 * 2、创建代理类。对Properties中的值进行判断,是否使用代理类


具体代码实现及详细思路,如下:

1、通知接口类

package com.proxy.aopframework;


import java.lang.reflect.Method;
/*
 * 创建通知接口,经过分析,由于在代理中,委托类执行前,执行后,
 * 都需要有通知功能,通知属于同一类型,那么封装成一个接口,供其他程序实现使用
 * 
 *  @author lijl
 * */
public interface AdviceInterface {
public void AdviceIn(Object reflect, Method method, Object[] arg);


}

------------------------------------------------------华丽丽的分割线——-------------------------------------------------------------------------


2、创建通知类


import java.lang.reflect.Method;
/*
 * 创建通知类,在代理中委托类执行前,执行
 * 
 *  @author lijl
 * */
public class AdviceBefore implements AdviceInterface{


@Override
public void AdviceIn(Object reflect, Method method, Object[] arg) {
// TODO Auto-generated method stub
System.out.println("AdviceBefore.AdviceIn()"+method);
}


}

----------------------------

package com.proxy.aopframework;


import java.lang.reflect.Method;
/*
 * 创建通知类,在代理中委托类执行后,执行
 * 
 *  @author lijl
 * */
public class AdviceAfter implements AdviceInterface{


@Override
public void AdviceIn(Object reflect, Method method, Object[] arg) {
// TODO Auto-generated method stub
System.out.println("AdviceAfter.AdviceIn()"+method);
}


}


-----------------------------------------------------------------------华丽丽的分割线----------------------------------------------------------------------------------------------------------------

3、代理类


package com.proxy.aopframework;
import java.lang.reflect.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/*
 *  创建代理类
 * 1、实现InvocationHandler接口
 * 2、实例化对象后,将委托类对象传递进来,使用setProxy方法
 * 3、在传递进来的同时,返回委托类的动态代理对象,使用Proxy的newProxyInstance方法,
 * pro.getClass().getClassLoader()  传递委托类的加载器,
 * pro.getClass().getInterfaces()   委托类的接口,
 * this                             本代理类的对象
 * 
 * 4、代理类DynamicProxy重写invoke方法,public Object invoke(Object proxy, Method method, Object[] args)
 * 5、在invoke方法中,使用反射技术,对委托类进行操作,在委托类执行前,记录日志通知,委托类执行后,记录日志通知
 * 6、对5进行详解,外界对AdviceInterface进行设置对象,使用set方法,如果不同的传值,执行不同的日志通知
 * 
 *  @author lijl
 * */
public class DynamicProxy implements InvocationHandler {
private Object pro;


AdviceInterface befor;
AdviceInterface after;
public Object setProxy(Object pro){
this.pro = pro;

Object obj = Proxy.newProxyInstance(pro.getClass().getClassLoader(), 
pro.getClass().getInterfaces(), this);
return obj;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if(befor != null)
befor.AdviceIn(proxy, method, args);

Object object = method.invoke(pro, args);

if(after != null)
after.AdviceIn(proxy, method, args);
return object;
}

public void setBefor(AdviceInterface befor) {
this.befor = befor;
}


public void setAfter(AdviceInterface after) {
this.after = after;
}

}


-----------------------------------------------------------------------华丽丽的分割线----------------------------------------------------------------------------------------------------------------

4、工厂类


package com.proxy.aopframework;


import java.io.*;
import java.util.*;
/*
 *  创建bean工厂类
1、使用IO技术读取配置文件config.properties,将读取的信息load到Properties键值对里
2、将Properties中的数据通过getProperty取出
3、通过反射技术,将取出来的类名进行实例化对象
4、对实例化的对象进行判断,如果配置信息的bean属于代理类DynamicProxy的类型,则继续取出active,target,将两个类实例化对象
5、将target目标类对象,通过代理类DynamicProxy的setProxy方法进行传值,返回Object类型对象,将该对象返回。
同时在中间进行判断,如果active通知类的对象与AdviceBefore(委托类执行前,执行通知类)相同,则执行setBefor方法
否则执行setAfter方法
6、如果bean不属于DynamicProxy类,则返回bean,不进行代理
 *  @author lijl
 * */
public class BeanFactory {
private Properties pt = new Properties();
public void bean() throws Exception{
FileReader fr = new FileReader("E:\\Workspaces\\MyEclipse Professional 2014\\exam\\src\\com\\proxy\\aopframework\\config.properties");
pt.load(fr);
System.out.println("BeanFactory.bean()");
}
public Object factory() throws Exception{
String name = pt.getProperty("xxx");
Class clazz = Class.forName(name);
Object bean = clazz.newInstance();
if(bean instanceof DynamicProxy){
String active = pt.getProperty("xxx.active");
String target = pt.getProperty("xxx.target");
Object clazz_target = Class.forName(target).newInstance();
Object clazz_active = Class.forName(active).newInstance();
Object dp =((DynamicProxy)bean).setProxy(clazz_target);
if(clazz_active instanceof AdviceBefore)
((DynamicProxy) bean).setBefor((AdviceInterface)clazz_active);
else if(clazz_active instanceof AdviceAfter)
((DynamicProxy) bean).setAfter((AdviceInterface)clazz_active);


return dp;
}
return bean;
}

}

-----------------------------------------------------------------------华丽丽的分割线----------------------------------------------------------------------------------------------------------------

5、主函数

public class test_main {
public static void main(String[] args) throws Exception{
BeanFactory e  = new BeanFactory();
e.bean();
Object sl = e.factory();
((List) sl).add("kkk");
}


6、结果:

BeanFactory.bean()
AdviceAfter.AdviceIn()public abstract boolean java.util.List.add(java.lang.Object)

通过以上代码以及分析,可以更清晰了解反射、动态代理,实现AOP思想的Spring框架

 -------android培训JAVA培训、期待与您交流! ----------

--------详细请查看www.itheima.com-------------


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章