java高新技术day-3

1.       jvm动态生成类

package cn.itcast.day3;

 

import java.lang.reflect.Constructor;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.util.Collection;

 

public class ProxyTest {

 

    /**

     * @param args

     */

    public static void main(String[] args) {

    Class clazzProxy1=Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);

   

    System.out.println("----begin constructersList---");//声明开始打印构造函数

    Constructor [] constructors=clazzProxy1.getConstructors();//用一个构造函数集合接收jvm产生的类的构造方法

    for (Constructor constructor : constructors) {

       String name=constructor.getName();//获得构造方法名

       StringBuilder sBuilder=new StringBuilder(name);//建立一个StringBuilder对象

       sBuilder.append('(');//在构造方法名后添加一个括号

       Class[] clazzParams=constructor.getParameterTypes();//获得构造方法的参数列表

       for (Class class1 : clazzParams) {

           sBuilder.append(class1.getName()).append('.');//获得参数名并加,号

       }

       if (clazzParams!=null&&clazzParams.length!=0) {

           sBuilder.deleteCharAt(sBuilder.length()-1);//如果有参数则去掉最后一个,号

       }

      

       sBuilder.append(')');//添加一个括号

       System.out.println(sBuilder);//打印该构造方法

    }

   

    System.out.println("----begin method---");//打印该类的方法列表,同理

    Method [] methods=clazzProxy1.getMethods();

    for (Method method : methods) {

       String name=method.getName();

       StringBuilder sBuilder=new StringBuilder(name);

       sBuilder.append('(');

       Class[] clazzParams=method.getParameterTypes();

       for (Class class1 : clazzParams) {

           sBuilder.append(class1.getName()).append('.');

       }

       if (clazzParams!=null&&clazzParams.length!=0) {

           sBuilder.deleteCharAt(sBuilder.length()-1);

       }

      

       sBuilder.append(')');

       System.out.println(sBuilder);

    }

   

    }

 

}

2.       基本代理方法

代理方法的参数

1:代理的是哪个对象 2:参数中的哪个方法 3:参数要传进来的参数

Collection proxy3=(Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(),

           new Class[]{Collection.class},

           new InvocationHandler()

           {

              ArrayList arrayList=new ArrayList();//要代理方法的对象

              public Object invoke(Object arg0, Method arg1, Object[] arg2)

                     throws Throwable {

                  long beginTime=System.currentTimeMillis();//方法开始时间

                  Object retVal=arg1.invoke(arrayList, arg2);//执行要代理的方法

                  long endTime=System.currentTimeMillis();//方法结束时间

                  System.out.println(endTime-beginTime);//方法运行用时

                  return retVal;//返回要代理方法的返回值

              }

             

           }

           );

    proxy3.add(1);//调用代理后的方法

    proxy3.add(2);

    proxy3.add(4);

    System.out.println(proxy3.size());//打印集合长度

3.    自定义一个代理的框架

1)  定义Advice接口

package cn.itcast.day3;

 

import java.lang.reflect.Method;

 

public interface Advice {

    void beforeMethod(Method method);//目标方法前调用的方法

    void afterMethod(Method method);//目标方法后调用的方法

}

2)  实例化Advice接口

package cn.itcast.day3;

 

import java.lang.reflect.Method;

 

public class MyAdvice implements Advice {

    long beginTime;

    long endTime;

    public void afterMethod(Method method) {

       endTime=System.currentTimeMillis();

       System.out.println(endTime-beginTime);

      

    }

 

    public void beforeMethod(Method method) {

       beginTime=System.currentTimeMillis();

      

    }

 

}

3)  制作代理框架

private static Object getProxy(final Object target/*需要代理的对象*/,final Advice advice/*该对象要添加的功能接口*/) {

       Object proxy3=Proxy.newProxyInstance(Object.class.getClassLoader()/*获得类加载器*/,

              target.getClass().getInterfaces()/*获得目标类的接口*/,

              new InvocationHandler()

              {

               

                  public Object invoke(Object arg0, Method method, Object[] para)

                         throws Throwable {

                    

                     advice.beforeMethod(method);//方法调用前操作

                     Object retVal=method.invoke(target, para);//执行要代理的方法

                      advice.afterMethod(method);//方法调用后的操作

                     return retVal;//返回要代理方法的返回值

                  }

                 

              }

              );

       return proxy3;

    }

4..实现类似Spring的可配置AOP框架

1)配置文件

#xxx=java.util.ArrayList

xxx=cn.itcast.day3.aopframework.ProxyFactoryBean

xxx.advice=cn.itcast.day3.MyAdvice

xxx.target=java.util.ArrayList

2)委托的添加方法代码

package cn.itcast.day3;

 

import java.lang.reflect.Method;

 

public class MyAdvice implements Advice {

    long beginTime;

    long endTime;

    public void afterMethod(Method method) {

       endTime=System.currentTimeMillis();

       System.out.println(endTime-beginTime);

      

    }

 

    public void beforeMethod(Method method) {

       beginTime=System.currentTimeMillis();

      

    }

 

}

3)  委托工厂

package cn.itcast.day3.aopframework;

 

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

 

import cn.itcast.day3.Advice;

 

public class ProxyFactoryBean {

    private Object target;//设置需要委托的类为该方法的属性

    private Advice advice;//设置aop

      

    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;

    }

 

    public Object getProxy() {

       Object proxy3=Proxy.newProxyInstance(Object.class.getClassLoader()/*获得类加载器*/,

              target.getClass().getInterfaces()/*获得目标类的接口*/,

              new InvocationHandler()

              {

               

                  public Object invoke(Object arg0, Method method, Object[] para)

                         throws Throwable {

                    

                     advice.beforeMethod(method);//方法调用前操作

                     Object retVal=method.invoke(target, para);//执行要代理的方法

                      advice.afterMethod(method);//方法调用后的操作

                     return retVal;//返回要代理方法的返回值

                  }

                 

              }

              );

       return proxy3;

    }

   

 

}

4)  bean工厂

package cn.itcast.day3.aopframework;

import java.io.*;

import java.util.Properties;

 

import cn.itcast.day3.Advice;

public class BeanFactory {

    Properties props=new Properties();//用来装载文件属性

    public BeanFactory(InputStream ips)

    {

       try {

           props.load(ips);//输入流

       } catch (IOException e) {

           e.printStackTrace();

       }

    }

    public Object getBean(String name) throws Exception//通过类名返回Bean

    {

       String className=props.getProperty(name);//获得要加载的名称

       Class clazz=Class.forName(className);//获得加载的类

       Object bean=clazz.newInstance();//实例化类

       if (bean instanceof ProxyFactoryBean) {//如果该类是委托工厂型的,则进入

           ProxyFactoryBean proxyFactoryBean=(ProxyFactoryBean)bean;//获得这个工厂

           Advice advice=(Advice)Class.forName(props.getProperty(name+".advice")).newInstance();//获得Advice子类的对象

           Object target=Class.forName(props.getProperty(name+".target")).newInstance();//获得要委托的类

           proxyFactoryBean.setAdvice(advice);//给工厂属性赋值

           proxyFactoryBean.setTarget(target);

           Object proxy=((ProxyFactoryBean)bean).getProxy();//获得target的委托类

           return proxy;

       }

       return bean;//返回原来的类

      

    }

}

5)  测试类

package cn.itcast.day3.aopframework;

 

import java.io.InputStream;

import java.util.Collection;

 

public class AopFrameworkTest {

 

 

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

       InputStream ips=AopFrameworkTest.class.getResourceAsStream("config.properties");//获得文件流

       Object bean=new BeanFactory(ips).getBean("xxx");//通过bean工厂获得bean

       System.out.println(bean.getClass().getName());//获得类型名 原类/委托类

       ((Collection)bean).clear();//调用方法

      

 

    }

 

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值