动态代理练习

1.接口有实现类(有目标方法)

package com.demo.demo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface LogService{
    void doSave();
}

class LogServiceImpl implements LogService{//目标对象
    public void doSave() {
        System.out.println("save Log");
    }
}

class LogAspect{
    public void before(){//Aspect(切面)
        System.out.println("method before");
    }
    public void after(){
        System.out.println("method after");
    }
}

public class TestProxy01 {
    //在此类的对象方法中调用目标方法,添加业务扩展功能
    static class ServiceHandler implements InvocationHandler{
        private Object target;
        private LogAspect logAspect=new LogAspect();
        public ServiceHandler(Object target){
            this.target=target;
        }
        public Object invoke(Object proxy,
                Method method, Object[] args) throws Throwable {
            //执行日志切面方法
            logAspect.before();
            //执行目标对象方法
            method.invoke(target, args);
            //执行日志切面方法
            logAspect.after();
            return null;
        }//整合核心业务调用与扩展业务调用
    }
    /**
     * 借助 JDK API(Proxy) 为目标对象创建动态代理对象
     * @param target
     * @return
     */
    static Object newLogServicePorxy(LogService target){
        LogService logService = (LogService)Proxy.newProxyInstance(
                target.getClass().getClassLoader(),    //loader 类的加载器
                target.getClass().getInterfaces(),    //interfaces 目标对象实现的接口
                new ServiceHandler(target));        //h 处理器,处理目标对象和 代理对象要织入扩展功能的业务的处理器
        return logService;
    }

    public static void main(String[] args) {
        LogService logService = (LogService) newLogServicePorxy(new LogServiceImpl());
        //当调用doSave方法时,系统底层会调用Handler对象的
        //invoke方法,执行核心业务与扩展业务的整合
        logService.doSave();
    }
}

2.接口没有实现类(即没有目标方法,仿照mybatis中的dao层)

package com.demo.demo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;

interface FindDao{
    Map<String,String> findDao(Integer i);
}

class DemoProxy implements InvocationHandler{
    public static Object finds(Class<?> target) {
        Object obj = Proxy.newProxyInstance(
                target.getClassLoader(), 
                new Class[]{target}, 
                new DemoProxy());
        return obj;
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("do invoke!!!");
        return null;
    }
    
}



public class TestProxy03 {
    public static void main(String[] args) {
        FindDao f=(FindDao) DemoProxy.finds(FindDao.class);
        f.findDao(5);
    }
    
}

3.没有实现一个接口,直接就是一个类,需要使用CGLIB来做动态代理

package com.demo.demo;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodProxy;
//目标对象
class HelloServiceImpl{
    public void sayHello(){
        System.out.println(" is ok !!! ");
    }
}

//如何借助CGLIB为如上对象创建一个代理对象
//通过代理对象扩展    如上对象的扩展功能

public class TestProxy04 {
    public static void main(String[] args) {
        //创建EnHancer对象(此对象为使用CGLIB入口对象)
        //要借助此对象为目标对象创建代理对象
        //这里的代理对象是目标对象的一个子类类型对象
        Enhancer h = new Enhancer();
        //设置代理对象要继承的那个父类的类型
        h.setSuperclass(HelloServiceImpl.class);
        //设置回调函数(当指定代理对象的方法时,会执行此Callback函数
        h.setCallback(new MethodInterceptor() {
            public Object intercept(
                    Object arg0,//指向代理对象
                    Method arg1,//目标对象的方法
                    Object[] arg2,//方法执行时实际参数
                    MethodProxy arg3//方法对象的代理
                    ) throws Throwable {
                System.out.println("before do");
                Object result = arg3.invokeSuper(arg0, arg2);
                System.out.println("after do");
                return result;
            }
        });//类似JDK动态代理的InvocationHandler
        
        Object obj = h.create();
        HelloServiceImpl hs = (HelloServiceImpl) obj;
        hs.sayHello();
    }
}

总结: AOP 底层基于代理机制实现功能扩展

  1.假如目标对象(被代理的对象)实现接口,则底层默认采用JDK动态代理机制为目标对象创建代理对象(目标类和代理类会实现共同接口)

  2.假如目标对象(被代理对象)没有实现接口,则底层默认采用CGLIB代理机制为目标对象创建代理对象(默认创建的代理类会继承目标对象类型)

原文地址:https://www.cnblogs.com/gxlaqj/p/11497150.html