动态代理实现Spring AOP

代理模式可谓是Spring框架AOP实现的基础,无意发现当service层使用事务时,注册到spring容器的是一个proxy对象,而无事务的service注册到容器就是非proxy对象。猜想如果某一个类是aop切入点时就使用代理对象。 以下是jdk动态代理的实现

/**
 * 
 *@Description:切面处理类
 *@Author:mf
 *@Since:2017年11月14日
 *@Version:1.1.0
 */
public class AopInvocationHandler implements InvocationHandler {

    /**
     * 目标对象
     */
    private Object target;

    /**
     * 拦截器
     */
    private List<AopIntercept> chains;

    public AopInvocationHandler(Object target, AopIntercept... handlers) {
        chains = Arrays.asList(handlers);
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = new AopProxy(proxy, target, method, args, chains).process();
        return result;
    }
}
/**
 * 
 *@Description:AOP静态代理类
 *@Author:mf
 *@Since:2017年11月14日
 *@Version:1.1.0
 */
public class AopProxy {
    private Object proxy;
    private Object target;
    private Method method;
    private Object[] args;
    private List<AopIntercept> chains;

    private int index = -1;

    public AopProxy(Object proxy, Object target, Method method, Object[] args, List<AopIntercept> chains) {
        this.proxy = proxy;
        this.target = target;
        this.method = method;
        this.args = args;
        this.chains = chains;
    }

    /**
     * 
     * @return
     * @throws Throwable
     * @author:mf
     * @Description:如果有拦截器则先执行拦截器,若无则执行方法
     */
    public Object process() throws Throwable {
        if (index == chains.size() - 1) {
            try {
                return method.invoke(target, args);
            } catch (InvocationTargetException e) {
                throw e.getCause();
            }
        }
        AopIntercept hander = chains.get(++index);
        return hander.intercept(proxy, method, args, this);
    }

/**
 * 
 *@Description:拦截器接口
 *@Author:mf
 *@Since:2017年11月14日
 *@Version:1.1.0
 */
public interface AopIntercept {

    /**
     * 
     * @param proxy
     * @param method
     * @param args
     * @param aop
     * @return
     * @throws Throwable
     * @author:mf
     * @Description:
     */
    public Object intercept(Object proxy, Method method, Object[] args, AopProxy aop) throws Throwable;
}
/**
 * 
 * @Description:日志拦截器
 * @Author:mf
 * @Since:2017年11月14日
 * @Version:1.1.0
 */
public class LoggerIntercept implements AopIntercept {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Override
    public Object intercept(Object proxy, Method method, Object[] args, AopProxy aop) throws Throwable {
        String params = doBefore(method, args);// 之前记录日志
        // 开始时间
        long start = System.currentTimeMillis();
        Object result = aop.process();// 继续执行
        // 结束时间
        long end = System.currentTimeMillis();
        log.info("-OUT \"{}\",COST:{}", params, (end - start) + "ms");
        return result;
    }

    private String doBefore(Method method, Object[] args) {
        StringBuilder params = new StringBuilder("");
        try {
            params.append(method.getDeclaringClass().getName()).append(".");
            params.append(method.getName());
            log.info("-IN \"{}\",PARAMS:{}", params, JSON.toJSONString(args,SerializerFeature.WriteMapNullValue));
        } catch (Exception e) {
            log.error("LoggerIntercept", e);
        }
        return params.toString();
    }
}
public class Test {

    public static void main(String[] args) {
        try {
            UserService service = Class.forName("package").newInstance();
            UserService serviceProx = getProxObj(UserService.class,service);
            System.out.println(service);
            service.save("1", "小毛");
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * 
     * @param inter
     * @param target
     * @return
     * @author:mf
     * @Description:获取动态代理对象
     */
    @SuppressWarnings("unchecked")
    private static <T> T getProxObj(Class<T> inter, T target) {
        //创建代理处理类,并添加切面处理类
        AopInvocationHandler h = new AopInvocationHandler(target, new LoggerIntercept());
        return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), new Class[] { inter }, h);
    }
}

这是一个简单的动态代理实现AOP的功能。

转载于:https://my.oschina.net/sofly/blog/1527130

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值