AOP初探
AOP初探
laichendong 发表于3年前
AOP初探
  • 发表于 3年前
  • 阅读 1072
  • 收藏 39
  • 点赞 1
  • 评论 5

腾讯云 技术升级10大核心产品年终让利>>>   

想说写一个系列,又不敢说写一个系列,害怕只有开头,却没有结尾。但不管怎么样,这篇还是要写下来,不然,就连开头都没有了。 这篇打算将两种实现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();
        }
    }
     
标签: AOP java
共有 人打赏支持
粉丝 9
博文 85
码字总数 71483
评论 (5)
never_say
有“深”探吗?
laichendong

引用来自“never_say”的评论

有“深”探吗?

酝酿中。。。
黄勇

引用来自“laichendong”的评论

引用来自“never_say”的评论

有“深”探吗?

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

引用来自“黄勇”的评论

引用来自“laichendong”的评论

引用来自“never_say”的评论

有“深”探吗?

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

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

引用来自“hww”的评论

引用来自“黄勇”的评论

引用来自“laichendong”的评论

引用来自“never_say”的评论

有“深”探吗?

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

勇哥写的Java那点事系列博客不错
多谢!博主这篇言简意赅,抓住了 AOP 精髓,期待后续更优秀的博文!
×
laichendong
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: