spring AOP代理是什么?要如何实现?

TheDisguiser 2020-07-24 17:28:59 java常见问答 8554

Spring两大核心aop和ioc几乎无人不知,在aop中有着代理模式这么一种功能,项目中非常有用,小伙伴们知道它吗?下面来看看如何来实现它吧。

什么是aop代理?

代理模式的核心作用就是通过代理,来控制对对象的访问。它的设计思路是:定义一个抽象角色,让代理角色和真实角色分别去实现它。

真实角色:实现抽象角色,定义真实角色所需要实现的业务逻辑,以供代理角色调用。它只关注真正的业务逻辑,如厨师炒菜。

代理角色:实现抽象角色,是真实角色的代理,会通过真实角色的业务逻辑方法来实现抽象方法,并在前后可以附加自己的操作,比如谈合同,布置场地,收钱等。

代理模式的设计思路就是以上了。其中,代理模式又分为静态代与和动态代理。静态代理就是我们自己创建一个代理类,而动态代理是程序自动帮我们生成代理。

怎么实现aop代理模式?

静态代理

/**
 * 代理类与目标类的共同接口
 */
public interface Subject
{
    void request();
    void response();
}
/**
 * 目标类
 */
public class RealSubject implements Subject
{
    @Override
    public void request()
    {
        System.out.println("执行目标对象的request方法......");
    }
    @Override
    public void response()
    {
        System.out.println("执行目标对象的response方法......");
    }
}
/**
 * 代理类
 */
public class ProxySubject implements Subject
{
    private Subject subject;
    public ProxySubject(Subject subject)
    {
        this.subject = subject;
    }
    @Override
    public void request()
    {
        System.out.println("before 前置增强");
        subject.request();
        System.out.println("after 后置增强");
    }
    @Override
    public void response()
    {
        System.out.println("before 前置增强");
        subject.response();
        System.out.println("after 后置增强");
    }
}
public class Main
{
    public static void main(String[] args)
    {
        //目标对象
        Subject realSubject = new RealSubject();
        //代理对象 通过构造器注入目标对象
        Subject proxySubject = new ProxySubject(realSubject);
        proxySubject.request();
        proxySubject.response();
    }
}

动态代理

1、JDK动态代理

/**
 * 自定义InvocationHandler的实现类
 */
public class JdkProxySubject implements InvocationHandler
{
    private Subject subject;
    public JdkProxySubject(Subject subject)
    {
        this.subject = subject;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
        System.out.println("before 前置通知");
        Object result = null;
        try
        {
            result = method.invoke(subject, args);
        }
        catch (Exception ex)
        {
            System.out.println("ex: " + ex.getMessage());
            throw ex;
        }
        finally
        {
            System.out.println("after 后置通知");
        }
        return result;
    }
}
public class Main
{
    public static void main(String[] args)
    {
        //获取InvocationHandler对象 在构造方法中注入目标对象
        InvocationHandler handler = new JdkProxySubject(new RealSubject());
        //获取代理类对象
        Subject proxySubject = (Subject) Proxy.newProxyInstance(Main.class.getClassLoader(), new Class[]
        {
            Subject.class
        }, handler);
        //调用目标方法
        proxySubject.request();
        proxySubject.response();
    }
}

2、CgLib动态代理

/**
 * 自定义MethodInterceptor实现类
 */
public class MyMethodInterceptor implements MethodInterceptor
{
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable
    {
        System.out.println("before 前置通知");
        Object result = null;
        try
        {
            result = methodProxy.invokeSuper(obj, args);
        }
        catch (Exception ex)
        {
            System.out.println("ex: " + ex.getMessage());
            throw ex;
        }
        finally
        {
            System.out.println("after 后置通知");
        }
        return result;
    }
}
public class Main
{
    public static void main(String[] args)
    {
        //获取Enhancer 对象
        Enhancer enhancer = new Enhancer();
        //设置代理类的父类(目标类)
        enhancer.setSuperclass(RealSubject.class);
        //设置回调方法
        enhancer.setCallback(new MyMethodInterceptor());
        //获取代理对象
        Subject proxySubject = (Subject) enhancer.create();
        //调用目标方法
        proxySubject.request();
        proxySubject.response();
    }
}

以上就是本篇文章的所有内容,对于代理模式大家一定都了解了吧,还有什么不懂的java架构师知识请尽情来我们网站寻找答案吧。

推荐阅读:

spring事务管理,spring如何管理事务?

什么是spring?spring原理是什么?详解

springboot多模块打包详解