SpringAOP源码阅读-基本组件

ProxyFactory是Spring框架提供的一个类,用于创建代理,今天我们简单和大家看一下,这个类如何使用,进而导出创建一个代理对象所需要的元素。

  1. 首先我们拥有下面这么一个对象
public class TestService {
    public void sayHello(){
        System.out.println("hello world");
    }
}

我们的目的是,代理该对象,并在方法调用前打印一些文字

  1. 定义方法调用前需要执行的动作
public class TestInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("before");
        return invocation.proceed();
    }
}

可以看到该类实现了MethodInterceptor

SpringAOP源码阅读-基本组件
image.png
  1. 创建主类
public class ProxyFactoryTest {

    public static void main(String[] args) {
        TestService testService = new TestService();
        testService.sayHello();

        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTarget(testService);
        proxyFactory.addAdvice(new TestInterceptor());
        TestService proxy = (TestService) proxyFactory.getProxy();
        proxy.sayHello();
    }
}
SpringAOP源码阅读-基本组件
image.png

阅读下主类代码,

  1. 创建一个TestService对象,调用sayHello(),输出hello world
  2. 创建一个ProxyFactory对象
    1. target设置为TestService对象
    2. 添加Advice为第二步定义的TestInterceptor
  3. 获取代理对象,并调用sayHello(),输出before hello world

从这段代码中我们可以清楚的看出,创建一个代理对象需要2个东西

  1. 目标对象
  2. Advice
SpringAOP源码阅读-基本组件
image.png

PointCut

PointCut = ClassFilter+ MethodMatcher

Advisor

PointCutAdvisor = Advice + PointCut

  1. 修改TestService添加一个方法
public class TestService {
    public void sayHello(){
        System.out.println("hello world");
    }

    public void noProxy(){
        System.out.println("不要被代理");
    }
}
  1. 主类调用新方法
    public static void main(String[] args) {
        TestService testService = new TestService();
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTarget(testService);
        proxyFactory.addAdvice(new TestInterceptor());
        TestService proxy = (TestService) proxyFactory.getProxy();
        proxy.sayHello();
        System.out.println("===========");
        proxy.noProxy();
    }
SpringAOP源码阅读-基本组件
image.png

可以发现我现在无法控制目标类的哪些方法被代理。如果想控制怎么办?

下面我们来解决一下如何控制

  1. 创建一个PointCut
public class XiXiPointCut implements Pointcut {
    @Override
    public ClassFilter getClassFilter() {
        return ClassFilter.TRUE;
    }
    @Override
    public MethodMatcher getMethodMatcher() {
        return new XiXiMethodMatcher();
    }

    private static class XiXiMethodMatcher implements MethodMatcher{
        @Override
        public boolean matches(Method method, Class<?> targetClass) {
            return method.getName().equals("sayHello");
        }

        @Override
        public boolean isRuntime() {
            return false;
        }

        @Override
        public boolean matches(Method method, Class<?> targetClass, Object... args) {
            return method.getName().equals("sayHello");
        }
    }
}
  1. 改造一下主类
    public static void main(String[] args) {
        TestService testService = new TestService();
        ProxyFactory proxyFactory = new ProxyFactory();

        proxyFactory.setTarget(testService);

        DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();
        defaultPointcutAdvisor.setPointcut(new XiXiPointCut());
        defaultPointcutAdvisor.setAdvice(new TestInterceptor());
        proxyFactory.addAdvisor(defaultPointcutAdvisor);

        TestService proxy = (TestService) proxyFactory.getProxy();
        proxy.sayHello();
        System.out.println("===========");
        proxy.noProxy();
    }
SpringAOP源码阅读-基本组件
image.png

只有sayHello()被代理。

这里我就不多说直接给结论

  • PointCutAdvisor = Advice + PointCut
  • PointCut = ClassFilter + MethodMatcher
SpringAOP源码阅读-基本组件
image.png

PointCut:进行筛选目标对象及方法Advice:代理动作的执行

总结

好的,今天这篇文章主要让大家接触一下AOP代理的相关接口,混个脸熟


原文始发于微信公众号(溪溪技术笔记):SpringAOP源码阅读-基本组件

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/207161.html

(1)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!