文档章节

AOP初探

laichendong
 laichendong
发布于 2014/06/25 09:27
字数 570
阅读 1076
收藏 39
想说写一个系列,又不敢说写一个系列,害怕只有开头,却没有结尾。但不管怎么样,这篇还是要写下来,不然,就连开头都没有了。 这篇打算将两种实现AOP的技术的hello world写一下。 我们知道,Java实现AOP,一般采用两种技术:
  1. 使用JDK的动态代理,在代理类中拦截方法的调用,然后做些手脚
  2. 使用类似cglib之类的工具,将AOP的代码在编译期“织入”进去,就是修改字节码。(更深的我也不知道了……)
一、先说使用动态代理的。
  1. Java限制被代理的的类必须实现一个接口。(因为代理类也去实现这个接口,而方法的调用是通过实现接口来实现多态的。)
    public interface TagetService {
        void doSomething();
    }
  2. 再是我们要代理的目标类,即要用aop拦截的方法。
    public class TagetServiceImpl implements TagetService {
    
        /**
         * 需要被拦截的方法
         */
        @Override
        public void doSomething() {
            System.out.println("doing something.");
        }
    }
  3. 然后我们就要编写我们自己的aop逻辑了。实现InvocationHandler接口,在invoke方法中写自己的逻辑代码。
    public class TargetServiceInvocationHandler implements InvocationHandler {
        /**
         * 代理的目标对象
         */
        private Object target;
    
        public TargetServiceInvocationHandler(Object target) {
            this.target = target;
        }
    
        /**
         * 拦截方法调用
         *
         * @param proxy  代理
         * @param method 方法
         * @param args   参数
         * @return
         * @throws Throwable
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("before do something.");
            Object result = method.invoke(target, args);
            System.out.println("after do something.");
            return result;
        }
    }
  4. 万事具备,组装起来,测试一下,(Spring AOP是不是帮我们优雅的组装了一下下?下一篇就研究一下他)
    public class Test {
    
        public static void main(String[] args) throws IllegalAccessException, InstantiationException {
            // service 实例
            TagetService instance = TagetServiceImpl.class.newInstance();
            // service 代理的实例
            TagetService tagetServiceProxy = (TagetService) Proxy.newProxyInstance(instance.getClass().getClassLoader(),
                    instance.getClass().getInterfaces(),
                    new TargetServiceInvocationHandler(instance));
            // 用代理的实例调用方法, 即会被handler拦截
            tagetServiceProxy.doSomething();
        }
    }
二、再来cglib的
  1. 这回被拦截的类不需要实现接口了
    public class TargetService {
        public void doSomething() {
            System.out.println("do something.");
        }
    }
  2. 通过实现cglig的MethodInterceptor接口,在intercept方法中实现我们的aop的逻辑
    public class TargetServiceInterceptor implements MethodInterceptor {
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println("before do something.");
            Object result = proxy.invokeSuper(obj, args);
            System.out.println("after do something.");
            return result;
        }
    }
  3. 组装起来测试一下下
    public class Test {
        public static void main(String[] args) {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(TargetService.class);
            enhancer.setCallback(new TargetServiceInterceptor());
            TargetService targetService = (TargetService) enhancer.create();
            targetService.doSomething();
        }
    }
     

© 著作权归作者所有

共有 人打赏支持
laichendong
粉丝 10
博文 85
码字总数 71483
作品 0
朝阳
程序员
私信 提问
加载中

评论(5)

黄勇
黄勇

引用来自“hww”的评论

引用来自“黄勇”的评论

引用来自“laichendong”的评论

引用来自“never_say”的评论

有“深”探吗?

酝酿中。。。
怎么才叫“深”探?我的结论是:工具一定要够长才行! http://my.oschina.net/huangyong/blog/161338

勇哥写的Java那点事系列博客不错
多谢!博主这篇言简意赅,抓住了 AOP 精髓,期待后续更优秀的博文!
已销号
已销号

引用来自“黄勇”的评论

引用来自“laichendong”的评论

引用来自“never_say”的评论

有“深”探吗?

酝酿中。。。
怎么才叫“深”探?我的结论是:工具一定要够长才行! http://my.oschina.net/huangyong/blog/161338

勇哥写的Java那点事系列博客不错
黄勇
黄勇

引用来自“laichendong”的评论

引用来自“never_say”的评论

有“深”探吗?

酝酿中。。。
怎么才叫“深”探?我的结论是:工具一定要够长才行! http://my.oschina.net/huangyong/blog/161338
laichendong
laichendong

引用来自“never_say”的评论

有“深”探吗?

酝酿中。。。
double9
double9
有“深”探吗?
极速开发,快就是这么任性,你不知道的Jfinal2.0新特性

Jfinal2.0新特性初探 Jfinal2.0发布了,我认为这个是里程碑式的发布,新加了不少好功能,这个博文主要是写个那些不想看文档,又想知道Jfinal2.0到底有什么新变动的同学们的,希望你们看完以后...

天蓬小猪
2015/06/19
0
10
C#进阶系列——DDD领域驱动设计初探(一):聚合

原文:C#进阶系列——DDD领域驱动设计初探(一):聚合 前言:又有差不多半个月没写点什么了,感觉这样很对不起自己似的。今天看到一篇博文里面写道:越是忙人越有时间写博客。呵呵,似乎有点...

杰克.陈
2017/12/19
0
0
初探java-agent

用了一下午总算把java agent给跑通了,本篇文章记录一下具体的操作步骤,以免遗忘。。。 通过java agent可以动态修改代码(替换、修改类的定义),进行AOP。 目标: ? 1 需要两个程序,一个是...

beibugulf
2016/10/21
89
0
初探设计:Java接口和类

今天犯了个错: “接口变动,伤筋动骨,除非你确定只有你一个人在用”。哪怕只是throw了一个新的Exception。哈哈,这是我犯的错误。 一、接口和抽象类 类,即“物以类聚”中的类,物则为一个...

泥沙砖瓦浆木匠
2015/12/05
2K
20
AOP那些学术概念—通知、增强处理连接点(JoinPoint)切面(Aspect)

1、我所知道的AOP 初看起来,上来就是一大堆的术语,而且还有个拉风的名字,面向切面编程,都说是OOP的一种有益补充等等。一下让你不知所措,心想着:管不得很多人都和我说AOP多难多难。当我...

iphoenix
2016/09/06
48
0

没有更多内容

加载失败,请刷新页面

加载更多

容器技术系列汇总

docker docker - 在centos7和windows10安装 docker - 镜像加速器 docker - 构建一个简单的docker镜像 docker - 调试Dockerfile docker - 常用命令 docker - Dockerfile常用指令 docker - doc......

细肉云吞
7分钟前
0
0
vue笔记 $set的正确用法

vue2.0 给data对象新增属性,并触发视图更新 如下代码,给 student对象新增 age 属性 data () { return { student: { name: '', sex: '' } } } 众所周知,直接给student赋值操作,虽然可以新...

Carbenson
7分钟前
0
0
Confluence 6 为边栏添加自定义内容

你可以使用 wiki 标记和自定义内容来对边栏进行更进一步的自定义。 希望添加自定义内容到你的边栏中: 进入空间后,然后从边栏的底部选择 空间工具(Space tools) > 外观和感觉(Look and ...

honeymose
12分钟前
0
0
从现在开始!(上海)

从现在开始,我要暂时告别开发了。开始从测试学起,希望自己在测试方面也会有晋升!

政旭Arvin
17分钟前
1
0
网易免费企业邮箱配置客户端

网易免费企业邮箱客户端(pop、imap、smtp)权限默认开启,对应服务器地址为: 发件服务器: SMTP:smtp.ym.163.com 默认端口为:25 (如勾选ssl安全链接,端口号为994) 收件服务器: POP3...

柴高八斗之父
20分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部