Java基础加强(二)

来源:互联网 发布:网络推广主要工作 编辑:程序博客网 时间:2024/05/02 01:34


Java基础加强()

一、类加载器

1.概念:类加载器就是加载类的工具。

2.Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类。

3.类加载器也是Java类。Java类的加载器本身也要被类加载器加载,显然必须有第一个加载器不是Java类,这正是BootStrap.

4.Java虚拟机中的所有类加载器采用具有父子关系的树形结构进行组织,在实例化每个类加载器对象时,需要为其指定一个父级类装载器对象或者默认采用系统装载器为其父级类加载。

5.类加载器的委托机制

    一、首先当前线程的类加载器去加载线程中的第一个类

    二、如果类A中引用了类BJava虚拟机将使用加载类A的类加载器加载类B

    三、直接调用ClassLoader.loadClass()方法指定某个类加载器去加载某个类

    四、每个类加载器加载器时,又委托给其上级类加载器。当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了,则抛ClassNotFoundException,不是再去找发起者类加载的儿子,因为没有getChild方法。

6.模板方法设计模式

         父类--->loadClass--->findClass//得到的class文件转换成字节码----->defineClass()

 

二、代理

1.程序中的代理:要为已存在的多个具有相同接口的目标类的各种方法增加一些系统功能,例如,异常处理、日志、计算方法的运行时间、事务管理等等。

2.Aop

系统中存在交叉业务,一个交叉业务就是要切入到系统中的一个方面,如下所示:

示:

                            安全   事务    日志

StudentService     ------|----------|------------|-------------

CourseService      ------|----------|------------|-------------

MiscService        ------|----------|------------|-------------

用具体的程序代码描述交叉业务:

method1    method2    method3

                   

------------------------------------------------------切面

....          ....          ......

------------------------------------------------------切面

                   }

交叉业务的编程问题即面向对象的编程问题(Aspect oriented program,简称AOP),AOP的目标就是要使交叉业务模块化。可以采用将切面代码移动到原始方法的周围,这与直接在方法中编写切面代码的运行效果是一样的,如下所示:

------------------------------------------------------切面

func1         func2            func3

                           

....            ....              ......

                           }

------------------------------------------------------切面

   3.动态代理技术

  3.1JVM可以在运行期动态的生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。

     3.2JVM生成的动态类必须实现一个或多个接口,所以,JVM生成的动态类只能用作具有相同接口的目标类的代理。

     3.3CGLIB库可以动态的生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。

 

     4.代理类的各种方法中通常除了要调用目标的相应方法和对外返回目标返回的结果,还可以在代理类中增加系统功能代码:

A、在调用目标方法之前

B、在调用目标方法之后

C、在调用目标方法的前后

D、在处理目标方法异常的catch块中

 

    5.动态代理的工作原理:Client(客户端)调用代理,代理的构造方法接受一个InvocationHandlerclient调用代理的各个方法,代理的各个方法请求转发给刚才通过构造方法传入的handler对象,又把各请求分发给目标的相应的方法.


    6.实现类似spring的可配置的AOP框架 

    一、工厂类BeanFactory

      1.工厂类BeanFactory负责创建目标类或代理类的实例对象,并通过配置文件实现切换。其getBean方法根据参数字符串返回一个相应的实例对象,如果参数字符串在配置文件中对应的类名不是ProxyFactoryBean,则直接返回该类的实例对象,否则返回该类示例对象的getProxy方法返回的对象。

      2.BeanFactory的构造方法接收代表配置文件的输入流对象的配置文件格式如下:

        #xxx=java.util.ArrayList

        xxx=cn.itcast.ProxyFactoryBean 

        xxx.target=java.util. ArrayList

        xxx.advice=cn.itcast.MyAdvice

        注:其中的#代表注释当前行。

      3.ProxyFactoryBean充当封装成动态的工厂,需为工厂提供的配置参数信息包括:

        目标(target

        通告(advice

      4.BeanFactoryProxyFactoryBean

          A.BeanFactory是一个纯粹的bean工程,就是创建bean及相应的对象的工厂。

          B.ProxyfactoryBeanBeanFactory中的一个特殊的Bean,是创建代理的工厂。

 

   二、实现类似spring的可配置的AOP框架的思路:

      1、创建BeanFactory类:

         A.构造方法:接受一个配置文件,通过Properties对象加载InputStream流对象获得。

         B.创建getBean(String name)方法,接收Bean的名字,从上面加载后的对象获得。

         C.通过其字节码对象创建实例对象bean

         D.判断bean是否是特殊的BeanProxyFactoryBean,如果是,就要创建代理类,并设置目标和通告,分别得到各自的实例对象,并返回代理类实例对象。如果不是在返回普通类的实例对象。

      2、创建ProxyFactoryBean(接口),此处用类做测试,其中有一个getProxy方法,用于获得代理类对象。

      3、对配置文件进行配置,如上面配置一样。

      4、作一个测试类:AopFrameworkTest进行测试。

 

//创建BeanFactory类     

package cn.itcast.test3.aopframework;    

import java.io.IOException;

import java.io.InputStream;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.util.Properties;

public class BeanFactory {    

    Properties prop = new Properties();    

    //创建对象时需要传入一个配置文件中的数据,所以需要在构造方法中接受一个参数     

    public BeanFactory(InputStream ips) {    

        try {    

            //将配置文件加载进来     

            prop.load(ips);    

        } catch (IOException e) {    

            e.printStackTrace();    

        }    

    }    

    //创建getBean方法,通过配置文件中的名字获取bean对象     

    public Object getBean(String name){    

        //从配置文件中读取类名     

        String className = prop.getProperty(name);    

        Object bean = null;    

        try {    

            //由类的字节码获取对象     

            Class clazz = Class.forName(className);    

            bean = clazz.newInstance();    

        } catch (Exception e) {    

            e.printStackTrace();    

        }     

        //判断bean是特殊的bean即ProxyFactoryBean还是普通的bean     

        if(bean instanceof ProxyFactoryBean){    

            Object proxy = null;    

            try {    

                //是ProxyFactoryBean的话,强转,并获取目标和通告     

                ProxyFactoryBean proxyFactoryBean = (ProxyFactoryBean)bean;    

                //获取advice和target     

                Advice advice = (Advice)Class.forName(prop.getProperty(name + ".advice")).newInstance();    

                Object target = Class.forName(prop.getProperty(name + ".target")).newInstance();    

                //设置目标和通告     

                proxyFactoryBean.setAdvice(advice);    

                proxyFactoryBean.setTarget(target);    

                //通过类ProxyFactoryBean(开发中是作为接口存在)中获得proxy对象     

                proxy = proxyFactoryBean.getProxy();    

            } catch (Exception e) {    

                // TODO Auto-generated catch block     

                e.printStackTrace();    

            }     

            //是ProxyFactoryBean的话,返回proxy对象     

            return proxy;    

        }    

        //否则返回普通bean对象     

        return bean;    

    }    

}    

    

//创建ProxyFactoryBean类     

package cn.itcast.test3.aopframework;    

import java.lang.reflect.*;    

import cn.itcast.test3.Advice;    

public class ProxyFactoryBean {    

    private Object target;   //定义目标变量 

private Advice advice;//定义通告变量 

//获取目标 

    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 proxy = Proxy.newProxyInstance(    

                target.getClass().getClassLoader(),    

                //这里的接口要和target实现相同的接口     

                target.getClass().getInterfaces(),    

                new InvocationHandler() {    

                    public Object invoke(Object proxy, Method method, Object[] args)    

                            throws Throwable {    

                        //通过契约,使用其方法--before和after方法     

                        advice.beforeMethod(method);    

                        Object value = method.invoke(target, args);    

                        advice.afterMethod(method);    

                        return value;    

                    }    

                }    

                );    

        return proxy;    

    }    

}    

//创建测试类AopFrameworkTest     

package cn.itcast.test3.aopframework;    

import java.io.InputStream;    

public class AopFramewrorkTest {    

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

        //读取配置文件的数据     

        InputStream ips =     

                AopFramewrorkTest.class.getResourceAsStream("config.property");    

        //获取bean对象     

        Object bean = new BeanFactory(ips).getBean("xxx");    

        System.out.println(bean.getClass().getName());    

    }    

}   

 

 

 

 

 

 

 

 

 

 

 


0 0
原创粉丝点击