java高新技术day-3

    技术2025-08-25  50

    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)