【后端开辟】java什么是代办?

【后端开辟】java什么是代办?,第1张

【后端开辟】java什么是代办?,第2张

java什么是代办?

代办是一种设想形式,供应了对目的对象别的的接见体式格局,即经由过程代办对象接见目的对象。


能够不修正目的对象,对目的对象功用举行拓展。


代办的作用:下降代码的冗余。


代办形式的完成分为两大类:静态完成和动态完成,动态完成依据完成的体式格局分为:jdk 动态完成,cglib动态完成

Java的三种代办形式

想要完成以上的需求有三种体式格局,这一部份我们只看三种形式的代码怎样写,先不触及完成道理的部份。


1、静态代办

public interface ISinger {
    void sing();
}

/**
 *  目的对象完成了某一接口
 */
public class Singer implements ISinger{
    public void sing(){
        System.out.println("唱一首歌");
    }  
}

/**
 *  代办对象和目的对象完成雷同的接口
 */
public class SingerProxy implements ISinger{
    // 吸收目的对象,以便挪用sing要领
    private ISinger target;
    public UserDaoProxy(ISinger target){
        this.target=target;
    }
    // 对目的对象的sing要领举行功用扩大
    public void sing() {
        System.out.println("向观众问好");
        target.sing();
        System.out.println("感谢人人");
    }
}

测试

/**
 * 测试类
 */
public class Test {
    public static void main(String[] args) {
        //目的对象
        ISinger target = new Singer();
        //代办对象
        ISinger proxy = new SingerProxy(target);
        //实行的是代办的要领
        proxy.sing();
    }
}

长处: 做到不修正目的对象的功用条件下,对目的功用扩大

瑕玷:这类完成体式格局很直观也很简朴,但其瑕玷是代办对象必需提早写出,假如接口层发生了变化,代办对象的代码也要举行保护。


假如能在运行时动态地写出代办对象,不只减少了一大批代办类的代码,也少了不停保护的懊恼,不过运行时的效力一定受到影响。


这类体式格局就是接下来的动态代办。


2、JDK代办

跟静态代办的条件一样,依然是对Singer对象举行扩大

public interface ISinger {
    void sing();
}

/**
 *  目的对象完成了某一接口
 */
public class Singer implements ISinger{
    public void sing(){
        System.out.println("唱一首歌");
    }  
}

这回直接上测试,因为java底层封装了完成细节(之后会细致讲),所以代码异常简朴,花样也基本上牢固。


挪用Proxy类的静态要领newProxyInstance即可,该要领会返回代办类对象

static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )

吸收的三个参数依次为:

 ● ClassLoader loader:指定当前目的对象运用类加载器,写法牢固

 ● Class<?>[] interfaces:目的对象完成的接口的范例,写法牢固

 ● InvocationHandler h:事宜处置惩罚接口,需传入一个完成类,平常直接运用匿名内部类

测试代码

public class Test{
    public static void main(String[] args) {
  Singer target = new Singer();
        ISinger proxy  = (ISinger) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("向观众问好");
                        //实行目的对象要领
                        Object returnValue = method.invoke(target, args);
                        System.out.println("感谢人人");
                        return returnValue;
                    }
                });
        proxy.sing();
    }
}

长处:动态完成了不转变目的对象逻辑的扩大

瑕玷:能够看出静态代办和JDK代办有一个配合的瑕玷,就是目的对象必需完成一个或多个接口,不然没法完成动态代办。


3、Cglib代办

条件条件:

 ● 须要引入cglib的jar文件,因为Spring的核心包中已包含了Cglib功用,所以也能够直接引入spring-core-3.2.5.jar

 ● 目的类不能为final

 ● 目的对象的要领假如为final/static,那末就不会被阻拦,即不会实行目的对象分外的营业要领

/**
 * 目的对象,没有完成任何接口
 */
public class Singer{

    public void sing() {
        System.out.println("唱一首歌");
    }
}
/**
 * Cglib子类代办工场
 */
public class ProxyFactory implements MethodInterceptor{
    // 保护目的对象
    private Object target;

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

    // 给目的对象建立一个代办对象
    public Object getProxyInstance(){
        //1.东西类
        Enhancer en = new Enhancer();
        //2.设置父类
        en.setSuperclass(target.getClass());
        //3.设置回调函数
        en.setCallback(this);
        //4.建立子类(代办对象)
        return en.create();
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("向观众问好");
        //实行目的对象的要领
        Object returnValue = method.invoke(target, args);
        System.out.println("感谢人人");
        return returnValue;
    }
}

这里的代码也异常牢固,只要标黄部份是须要本身写出

测试

/**
 * 测试类
 */
public class Test{
    public static void main(String[] args){
        //目的对象
        Singer target = new Singer();
        //代办对象
        Singer proxy = (Singer)new ProxyFactory(target).getProxyInstance();
        //实行代办对象的要领
        proxy.sing();
    }
}

长处:动态完成了不转变目的对象逻辑的扩大

瑕玷:目的必需完成接口,不然没法完成动态代办

总结:三种代办形式各有优瑕玷和响应的适用范围,主要看目的对象是不是完成了接口。


以Spring框架所挑选的代办形式举例

在Spring的AOP编程中:

假如到场容器的目的对象有完成接口,用JDK代办

假如目的对象没有完成接口,用Cglib代办

以上就是java什么是代办?的细致内容,更多请关注ki4网别的相干文章!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/zaji/552913.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2019-11-18
下一篇 2019-11-18

发表评论

登录后才能评论

评论列表(0条)

保存