java的静态代理,jdk代理和cglib代理例子

一:静态代理

  在使用静态代理时,需要定义接口或者父类。被代理对象(目标对象)和代理对象都需要实现同一接口或者继承父类。

  使用步骤:

  1:定义一个接口IStudentDao

  2:被代理对象(目标对象)StudentDao实现接口

  3:代理对象StudentDaoProxy也需要实现接口

  4:代理对象调用被代理对象方法

  具体实现:

  IStudentDao
public interface IStudentDao {
    void study();
}

   StudentDao

public class StudentDao  implements IStudentDao{
    @Override
    public void study() {
        System.out.println("小明正在学习中...");
    }
}

  StudentDaoProxy

public class StudentDaoProxy implements IStudentDao {
    private IStudentDao stu;//被代理对象,通过接口依赖

    public StudentDaoProxy(IStudentDao stu) {
        this.stu = stu;
    }

    @Override
    public void study() {
        System.out.println("被代理对象方法执行前..."); //这里可以写一些增强方法
        stu.study();
        System.out.println("被代理对象方法执行后...");
    }
}

  Client

public class Main {

    public static void main(String[] args) throws IllegalAccessException, InstantiationException {
       // IStudentDao stu = new StudentDao();//代理对象
        IStudentDao proxyStu = new StudentDaoProxy(StudentDao.class.newInstance());//代理对象
        proxyStu.study();
    }
}

 运行结果:

 

 

 二:JDK动态代理

  jdk动态代理是代理模式实现的一种方法。也是需要实现接口的。主要是通过反射来动态生成代理类。被代理对象需要实现接口,代理对象不需要实现接口;

  生成代理对象的JDK API:

/**
*loader:类加载器
*interfaces:被代理类实现的接口
*h:重写invocationHandler中的invoke,
*return:返回一个代理对象
*/
public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)
        throws IllegalArgumentException

  IStudentDao:

public interface IStudentDao {

    void study();

}

  StudentDao

public class StudentDao implements IStudentDao {
    @Override
    public void study() {
        System.out.println("小明正在学习......");
    }
}

  ProxyFactory:

//实现InvocationHandler接口,重写invoke方法
public class ProxyFactory implements InvocationHandler{

    private Object target;//被代理的对象;

    public ProxyFactory(Object target) {
        this.target = target;
    }

    //返回一个代理对象
    public Object getProxyInstance()
    {



        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                this
        );
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("jdk代理开始");
        Object invoke = method.invoke(target, args);

        System.out.println("jdk代理结束");

        return invoke;
    }
}

  测试:

public class Main {


    public static void main(String[] args) throws IllegalAccessException, InstantiationException {
        IStudentDao stu = new StudentDao();
        IStudentDao instance = (IStudentDao)new ProxyFactory(stu).getProxyInstance();
        instance.study();
    }
}

  结果:

 

 三:cglib实现动态代理

  无论是静态代理或者是jdk动态代理都需要实现一个接口。有时候我们只有一个对象,没有实现任何接口的。这时候可以使用目标对象子类来实现动态代理。cglib代理

通过在内存中构建子类从而实现对目标对象方法的扩建。

  先导入依赖:

<!-- https://mvnrepository.com/artifact/cglib/cglib -->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.2.8</version>
        </dependency>

  StudentDao

public class StudentDao {

    public void study()
    {
        System.out.println("小明正在学习......");
    }
}

  ProxyFactory

public class ProxyFactory  implements MethodInterceptor {

    private Object target;

    public ProxyFactory(Object target) {
        this.target = target;
    }


    public Object getProxyInstance()
    {
        //1.创建一个工具类
        Enhancer enhancer = new Enhancer();
        //2.设置父类
        enhancer.setSuperclass(target.getClass());
        //3.设置回调函数
        enhancer.setCallback(this);
        //4.创建子类,即代理对象
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("cglib代理开始");
        Object res = method.invoke(target, objects);
        System.out.println("cglib代理结束");

        return res;
    }
}

  Main

public class Main {

    public static void main(String[] args) throws IllegalAccessException, InstantiationException {
        ProxyFactory proxyFactory = new ProxyFactory(StudentDao.class.newInstance());
        StudentDao instance = (StudentDao)proxyFactory.getProxyInstance();
        instance.study();

    }
}

  

 

 四:总结

1:静态代理和jdk动态代理都需要实现接口,而cglib不用实现接口。
2:代理模式可以在不修改被代理对象(目标对象)的前提下,对目标对象进行扩展。
3:静态代理每次修改接口都需要维护目标对象和被代理对象。
4:你所热爱的,就是你的生活。

  

 

 

 

 

posted @ 2020-05-07 15:51  贼心~不死  阅读(175)  评论(0编辑  收藏  举报