------- android培训、java培训、期待与您交流! ----------
接上两篇技术文档,对代理模式的最后总结,建议spring框架开发,那么模拟一个需求如下:
config,peroperties文件如下:
xxx=com.proxy.aopframework.DynamicProxy
#xxx=java.util.ArrayList
xxx.active=com.proxy.aopframework.AdviceAfter
xxx.target=java.util.ArrayList
具体代码实现及详细思路,如下:
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、创建通知类
/*
* 创建通知类,在代理中委托类执行前,执行
*
* @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");
}
BeanFactory.bean()
AdviceAfter.AdviceIn()public abstract boolean java.util.List.add(java.lang.Object)
通过以上代码以及分析,可以更清晰了解反射、动态代理,实现AOP思想的Spring框架
-------android培训、JAVA培训、期待与您交流! ----------
--------详细请查看www.itheima.com-------------