随笔jar

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

首先:
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
@Component
public 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值