黑马程序员-动态代理

来源:互联网 发布:oracle nvl 转 mysql 编辑:程序博客网 时间:2024/06/06 01:46
 
黑马程序员-动态代理 - bb380667063 - Sun的博客

创建方式:

Collection  proxy=(Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(),new Class[ ] {Collection.class},new InvocationHandler(){ArrayList target = new ArrayList();public void invoke(Object proxy,Method method,Object[ ] args)throws Throwable{return method.invoke(target,args);}});proxy.add("abc");proxy.add("qwe");

invoke方法中的三个参数:代理对象,所使用的方法,方法参数。代理每调用一次方法。都会调用一次invoke方法。
在参数传入之前和返回之前都可以做一些操作。

如果代理接口包含某一方法,它的名称和参数签名与 java.lang.Object 的 hashCodeequals 或 toString 方法相同,那么在代理实例上调用这样的方法时,传递到调用处理程序的 Method 对象将使 java.lang.Object 成为其声明类。除了这三个方法,都不会交给invocationhandler,而是调用自己的方法。

实现类似spring的可配置的AOP框架:
通过读取配置文件,获得客户所需要的类或者代理。如果需要代理,则载入目标和要求,返回含有附加功能的代理类。
主类的代码:
public class FactoryText {//主类创建输入流对象读取配置文件。通过配置文件去获取bean对象public static void main(String[] args)throws Exception {InputStream is = FactoryText.class.getResourceAsStream("config.properties");Object bean=new BeanFactory(is).getBean("xxx");System.out.println(bean.getClass().getName());}}
Bean工厂的代码:
public class BeanFactory {Properties pro = new Properties();public  BeanFactory(InputStream is)throws Exception{//通过构造函数将配置文件加载到properties存储。pro.load(is);}public Object getBean(String name)throws Exception{String className=pro.getProperty(name);Class clazz=Class.forName(className);Object bean = clazz.newInstance();if(bean instanceof ProxyFactoryBean){//如果需要的是代理类。则建立代理工厂类对象,然后将请求和目标同时传给代理类。并且返回代理对象。ProxyFactoryBean pfb=(ProxyFactoryBean)bean;Advice advice=(Advice)Class.forName(pro.getProperty(name+".advice")).newInstance();Object target=Class.forName(pro.getProperty(name+".target")).newInstance();pfb.setAdvice(advice);pfb.setTarget(target);Object proxy=pfb.getProxy();return proxy;}return bean;}}
代理工厂类的代码:
public class ProxyFactoryBean {private Advice advice;public Advice getAdvice() {return advice;}public void setAdvice(Advice advice) {this.advice = advice;}public Object getTarget() {return target;}public void setTarget(Object target) {this.target = target;}private Object target;//通过传入的advice和target创建代理对象。public Object getProxy(){Object cProxy=Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {advice.beforMethod(method);Object obj=method.invoke(target, args);advice.afterMethod(method);return obj;}});return cProxy;}}
advice接口和对象
public interface Advice {public void beforMethod(Method method);public void afterMethod(Method method);}
public class MyAdvice implements Advice {long begin;public void beforMethod(Method method) { begin=System.currentTimeMillis();System.out.println("开始");System.out.println(method.getName()+"running");}@Overridepublic void afterMethod(Method method) {long end = System.currentTimeMillis();System.out.println("结束"+(end-begin));}}
配置文件信息:
#xxx=java.util.ArrayList
xxx=aopFramWork.ProxyFactoryBean
xxx.advice=javaenhance.cn.day3.MyAdvice
xxx.target=java.util.ArrayList