栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

动态代理、jdk代理、cglib代理以及枚举的理解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

动态代理、jdk代理、cglib代理以及枚举的理解

静态代理

与动态代理的区别:在代码编译时就确定了所需要代理的类,静态代理的代理类只针对一个被代理类,动态代理在代码编译时

期还不能确定所需要代理的类,只能根据类的动态加载机制,在代码运行时加载被代理得类,动态代理可以针对多个被代理类(委托类)

示例

(由于Java api 机制 代理类和委托类必须要实现他们共同的接口)

package top;

import top.TopInterface;



public class StaticAgency implements TopInterface {

    public void palyGame(String gameName, String desc) {
        System.out.println("告知委托人"+gameName+"...."+desc);
    }

    public void eat(String foodName, String des) {
        System.out.println("告知委托人"+foodName+"....."+des);
    }
}

package top;

import lombok.Data;


@Data
public class Agency implements TopInterface{

    private StaticAgency staticAgency;

    public void palyGame(String gameName, String desc) {
        System.out.println("代理告知");
        staticAgency.palyGame(gameName, desc);
        System.out.println("代理告知结束");
    }

    public void eat(String foodName, String des) {
        System.out.println("代理告知");
        staticAgency.eat(foodName, des);
        System.out.println("代理告知结束");
    }
}

import org.junit.Test;
import top.Agency;
import top.StaticAgency;


public class TestDemo {
    @Test
    public void text(){
        Agency agency = new Agency();
        agency.setStaticAgency(new StaticAgency());
        agency.palyGame("开始游戏时间","真好玩");
        agency.eat("吃个桃桃","好凉凉");
    }


}

package top;



public interface TopInterface {
    void palyGame(String gameName, String desc);
    void eat(String foodName,String des);
}

总结:

从以上代码可以看出代理类拥有委托类的所有属性和方法,而方法真正的执行者是委托类,代理类可以在委托类方法执行方法之前和之后添加功能

JDK 代理

jdk代理属于接口代理,是由jdk提供的代理,jdk产生代理需要被代理类和代理类实现同一个接口,根据双方的共同的接口去产生

的代理对象,产生的代理对象为接口的实现类

package dynamicproxy;



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


public class JDKProxy implements InvocationHandler {
    //目标类
    private Object obj;

    public JDKProxy(Object obj) {
        this.obj = obj;
    }
    public JDKProxy(){
        super();
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("真实对象执行方法之前");
        //调用真实对象的方法
        Object invoke = method.invoke(obj, args);
        System.out.println("真实对象执行方法之后");
        return invoke;
    }
}

import dynamicproxy.JDKProxy;
import org.junit.Test;
import top.StaticAgency;
import top.TopInterface;

import java.lang.reflect.Proxy;


public class ProxyJdkText {
    @Test
    public void text(){
       TopInterface topService = new StaticAgency();
       //代理工厂产生代理实例
        JDKProxy jdkProxy = new JDKProxy(topService);
        //将代理的实例赋值给接口的引用(根据jdk自带的代理类方法)
        TopInterface top = (TopInterface) Proxy.newProxyInstance(
                topService.getClass().getClassLoader(),
                topService.getClass().getInterfaces(),
                jdkProxy);
        top.palyGame("小猪佩奇","很二");
        top.eat("猪shit","很香");

    }
}

cglib 代理

cglib 代理为子类代理,代理类和被代理类不需要实现同一个接口,产生的代理类为被代理类的子类也就是说此代理类继承了

被代理类,属于第三方框架 ,依靠ASM 字节码框架才能产生

package dynamicproxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;


public class CglibProxy implements MethodInterceptor {
    //目标对象
    private Object obj;

    public CglibProxy(Object obj) {
        this.obj = obj;
    }
    public CglibProxy(){}
    
    public Object createProxy() {
        Enhancer enhancer = new Enhancer();
        //回调函数  
        enhancer.setCallback(this);
        //设置代理对象的父类
        enhancer.setSuperclass(this.obj.getClass());
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("真实对象执行方法之前");
        //调用真实对象的方法
        Object invoke = method.invoke(obj, objects);
        System.out.println("真实对象执行方法之后");
        return invoke;

    }
}

import dynamicproxy.CglibProxy;
import entity.RealClass;
import org.junit.Test;


public class CglibText {
    @Test
    public void Test(){
        RealClass topService = new RealClass();
      CglibProxy cglibProxy = new CglibProxy(topService);
        RealClass proxy = (RealClass) cglibProxy.createProxy();
        proxy.realMethod();

    }

}

package entity;


public class RealClass {
    public void realMethod(){
        System.out.println("真实类方法");
    }
}

枚举(enum)

java 1.5 之后推出的一种专门存储整型常量的集合,可以以面向对象的思维去控制这些整型常量

魔法值:

一些带有歧义的变量值,比如 0 和1

我们可以把这个两个数字看作一种状态或者就是他们本身所代表的数字

为了改善我们可以将这种有歧义的变量放入枚举中用一个具体的值来代替它

package myenum;


enum State {
    

    SHADOW (0,"关闭"),OPEN(1,"开启");
    private int i;
    private String desc;
    private State(int i, String desc) {
        this.i = i;
        this.desc = desc;
    }
}

特点

  1. 枚举的定义和实例是放在一起的
  2. 枚举可以提供构造器,但构造器必须私有
  3. 枚举的实例必须放在第一行

使用

State.SHADOW.value

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/572694.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号