动态代理(Spring框架)

什么是动态代理?

举个例子,生活中一般在打官司的时候都会请代理律师,为什么要请律师呢?是因为开庭的时候大部人对于打官司没有经验,只会说出自己案件的陈述,并不会根据法律等争取自己权益的最大化,此时就可以请律师帮助自己不仅完成对案件的陈述,还能争取权益最大化。那么Java中也是一样,如果要对功能进行增强就可以使用动态代理

它通过java反射机制,获取某个被代理类的所有接口,并创建代理类 

为什么要用动态代理? 

动态代理使我们免于去重写接口中的方法,而着重于去扩展相应的功能或是方法的增强,与静态代理相比简单了不少,减少了项目中的业务量

Java的JDK中Proxy类可以实现基于接口的动态代理,实现步骤示例如下:

1.核心类的接口

package com.wang.service;

public interface Actor {
    void sring();

    void dance();

    void rap();
}

2. 实现核心接口中的抽象方法

package com.wang.service.impl;

import com.wang.service.Actor;

public class CXK implements Actor {
    @Override
    public void sring() {
        System.out.println("顶你太美");
    }

    @Override
    public void dance() {
        System.out.println("丁丁舞");
    }

    @Override
    public void rap() {
        System.out.println("练习时长两年半");
    }
}

3. 实现增强类

package com.wang.advice;

import com.wang.service.Actor;
import com.wang.service.impl.CXK;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class JJGS {
    public static void main(String[] args) {
        //1.创建被代理类的对象----具体的人物cxk
        Actor cxk = new CXK();
        //2.创建代理的对象----具体某个人为上面cxk服务
        /**
         * Object proxy:被代理对象的引用,系统会自动创建被代理对象的一个映射
         * Method method:被代理对象的方法
         *  Object[] args:被代理对象方法的参数
         *  返回值是  被代理对象执行后的返回值
         */
        Actor jjr = (Actor) Proxy.newProxyInstance(CXK.class.getClassLoader(), CXK.class.getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                System.out.println("演出前的增强: 联系业务");
                System.out.println("演出前的增强:互联网造势");
                System.out.println("演出前的增强:演出前的宣传");

                //被代理对象方法的执行,并获得返回值
                Object result=null;
                result=method.invoke(cxk,args);

                System.out.println("演出后的增强: 结算费用并纳税");

                return result;
            }
        });
        //3.有代理对象执行方法的时候不再是被代理对象执行方法,而是由我们的代理类对象执行方法
        jjr.rap();
    }
}

基于子类的CGLib动态代理,可以使用Enhancer类完成直接对某个类进行动态代理。具体操作步骤如下:

导入lib中的jar包

动态代理(Spring框架)_第1张图片

 

1.核心类的接口

package com.wang.service;

public interface BookService {
    //添加
    int save(int n);

    //删除
    int del();

    //修改
    int update();

    //查询
    void find();
}

2.实现核心类的抽象方法

package com.wang.service.impl;

import com.wang.service.BookService;

public class BookServiceImpl implements BookService {
    @Override
    public int save(int n) {
        System.out.println("添加");
        return 1;
    }

    @Override
    public int del() {
        System.out.println("删除");
        return 1;
    }

    @Override
    public int update() {
        System.out.println("修改");
        return 1;
    }

    @Override
    public void find() {
        System.out.println("查询");
    }
}

3.编写代理类

package com.wang.advice;

public class Loger {
    public void before(){
        System.out.println("前置通知: 执行日志的打印");
    }
    public void after(){
        System.out.println("后置通知:执行日志的打印");
    }

    public void afterThrowingPrintLog(){
        System.out.println("异常通知");
    }

    public void afterPrintLog(){
        System.out.println("最终通知:作资源的释放");
    }
}

4编写动态代理的xml文件


    
    
    


    
    
        
            
            
            
            
        
    

5.测试类(执行核心文件中的添加方法,完成增强功能)

package com.wang.servlet;

import com.wang.service.BookService;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test01 {

    @Test
    public void test01(){
        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
        BookService bookService = context.getBean(BookService.class);

        bookService.save(1);
    }
}

结果为:

动态代理(Spring框架)_第2张图片

 

你可能感兴趣的:(spring,java,后端)