随笔jar

来源:互联网 发布:sql查询分析执行 编辑:程序博客网 时间:2024/06/06 08:33

今天无事,看了下动态代理模式,就自己写了个通过配置文件添加日志的功能

首先:
1、要使用代理模式,需要一个类实现InvocationHandler接口,并且实现invoke()方法

package com.xingyao.aop;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import org.aspectj.lang.annotation.Aspect;import org.springframework.stereotype.Component;@Aspect@Componentpublic class LogInterceptor implements InvocationHandler {    private Object target;    public void before() {        System.out.println("程序运行前");    }    /**     * proxy:这个参数没有用到,在java文档中这样描述的     * (An instance method in a subclass with the same signature      * (name, plus the number and the type of its parameters)      * and return type as an instance method in the superclass     * overrides the superclass's method)     * 就是要求方法签名(名称与参数)与返回类型保持一致     * method:被代理对象的方法执行时需要用到     * args:执行代理对象的方法需要传递的参数     */    public Object invoke(Object proxy, Method method, Object[] args)            throws Throwable {        before();        method.invoke(target, args);        return null;    }    public Object getTarget() {        return target;    }    public void setTarget(Object target) {        this.target = target;    }}

这样就能将这个类变成动态代理类

2、然后就是执行动态代理对象

package com.xingyao.service;import java.lang.reflect.Proxy;import com.xingyao.aop.LogInterceptor;import com.xingyao.dao.UserDao;import com.xingyao.dao.impl.UserDaoImpl;import com.xingyao.model.User;public class UserServiceTest {    public static void main(String[] args) {        //被代理对象        UserDao userDAO = new UserDaoImpl();        //代理类的实例        LogInterceptor li = new LogInterceptor();        //将被代理对象传递给代理类        li.setTarget(userDAO);        //返回一个被代理对象化的实例        UserDao userDAOProxy = (UserDao)Proxy.newProxyInstance(userDAO.getClass().getClassLoader(), new Class[]{UserDao.class}, li);        //使用这个方法就能在执行userDAO.add()方法的时候添加代理对象的方法        userDAOProxy.add(new User());    }}

这是没有进行封装的动态代理,每次使用的使用都要new出代理对象出来,然后传递被代理对象,最后得到被代理化的实例。使得程序复杂化

我的改进:通过配置xml文件,将被代理类与代理类进行配置,从而调用getProxy(String idName)方法自动返回一个代理化的实例
1、其中代理类是随着你的需求自己完成
2、配置Resource.xml,配置结构如下

<?xml version="1.0" encoding="UTF-8"?><resources>    <!-- 通过配置id的值,得到你需要的代理化对象实例 -->    <type id="user">        <!-- 配置代理类对象的类名 -->        <LogClassName>com.xingyao.aop.LogInterceptor</LogClassName>        <!-- 配置被代理对象的类名 -->        <ProxyName>com.xingyao.dao.impl.UserDaoImpl</ProxyName>    </type></resources>

3、调用MyProxy中的getProxy(String idName)方法得到代理化对象
其中该方法实现如下

import java.lang.reflect.InvocationHandler;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import com.xingyao.Exception.AnalysisException;import com.xingyao.proxy.utils.ProxyXMLUtils;public class MyProxy {    public static Object getProxy(String idName) throws AnalysisException {        String logClassName = ProxyXMLUtils.getLogClassName(idName);        String proxyName = ProxyXMLUtils.getProxyName(idName);        try {            Object logClass = Class.forName(logClassName).newInstance();            Object proxyClass = Class.forName(proxyName).newInstance();            Method logSetTargetMethod = logClass.getClass().getDeclaredMethod("setTarget", Object.class);            logSetTargetMethod.invoke(logClass, proxyClass);            return Proxy.newProxyInstance(proxyClass.getClass().getClassLoader(), proxyClass.getClass().getInterfaces(), (InvocationHandler) logClass);        } catch (IllegalArgumentException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        } catch (InstantiationException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        } catch (SecurityException e) {            e.printStackTrace();        } catch (NoSuchMethodException e) {            e.printStackTrace();        } catch (InvocationTargetException e) {            e.printStackTrace();        }        return null;    }}

这里对xml的解析使用的是我专门为Resource.xml专门封装过的ProxyXMLUtils类
4、调用方式如下

package com.xingyao.proxy;import com.xingyao.Exception.AnalysisException;import com.xingyao.dao.UserDao;import com.xingyao.model.User;import com.xingyao.proxy.MyProxy;public class MyProxyTest {    public static void main(String[] args) throws AnalysisException {        UserDao userDAOProxy = (UserDao) MyProxy.getProxy("user");        userDAOProxy.add(new User());    }}

这里就极大的简便了动态代理方法的使用

0 0
原创粉丝点击