zoukankan      html  css  js  c++  java
  • java 实现类似spring的可配置的AOP框架

    一、工厂类BeanFactory:

    1、工厂类BeanFactory负责创建目标类或代理类的实例对象,并通过配置文件实现切换。

    2、getBean方法根据参数字符串返回一个相应的实例对象,如果参数字符串在配置文件中对应的类名不是ProxyFactoryBean,则直接返回该类的实例对象,否则返回该类示例对象的getProxy方法返回的对象。

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

    #xxx=java.util.ArrayList

    xxx=cn.itcast.test3.aopframework.ProxyFactoryBean

    xxx.advice=cn.itcast.test3.MyAdvice

    xxx.target=java.util. ArrayList

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

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

    目标(target)

    通告(advice)

    5、BeanFactory和ProxyFactoryBean:

    1)BeanFactory是一个纯粹的bean工程,就是创建bean即相应的对象的工厂。

    2)ProxyfactoryBean是BeanFactory中的一个特殊的Bean,是创建代理的工厂。

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

    1、创建BeanFactory类:

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

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

    3)通过其字节码对象创建实例对象bean。

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

    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());   

        }   

    }  

  • 相关阅读:
    usb mtp激活流程【转】
    [RK3288][Android6.0] USB OTG模式及切换【转】
    简单实用的磁带转MP3方法图解
    使用log4j的邮件功能
    hive从查询中获取数据插入到表或动态分区
    map和reduce 个数的设定 (Hive优化)经典
    Mysql ERROR 145 (HY000)
    Mysql计算时间差
    小米刷机教程和GAE for android
    Hbase 使用方法
  • 原文地址:https://www.cnblogs.com/fanweisheng/p/11137873.html
Copyright © 2011-2022 走看看