Spring AOP浅谈

一、AOP是什么?

大家都知道这是什么,“面向切面编程”(Aspect-Oriented Programming)。此处对于,定义以及概念就不在赘述,请自行查阅。

二、为什么需要AOP?

为什么需要AOP?换句话说,AOP帮我们解决了什么问题呢?
大家熟知的JDBC代码块,开始连接数据库,最后关闭数据库连接。这样一个过程,大家需要重复的写拿连接,关连接的代码。
因此,我们只需要中间的那一段代码就可以了,两端的完全可以与之分离开来。再如性能监控,权限控制,日志记录等等。
以上的情况下,显然我们需要在这个点上横向的做一些操作。这不仅简化代码,提高开发效率,
也将上述所说的“大家都做的”那部分代码从核心的业务逻辑中剥离出来进行解耦,更专注于业务逻辑的部分。

三、如何实现?

定义以下接口:

public interface Worker {
    void doJob(String doing);
}

实现类:

public class CoderImpl implements Worker {
    @Override
    public void doJob(String doing) {
        System.out.println("Your job is" + doing);
    }
}

直接写在实现类里:

public class CoderImpl implements Worker {
    @Override
    public void doJob(String doing) {
        before();
        System.out.println("Your job is" + doing);
        after();
    }

    private void before(){
        System.out.println("working before...");
    }

    private void after(){
        System.out.println("working after...");
    }
}

如上写死代码显然不是好的办法,所以可以通过以下解决:
· 静态代理
· JDK动态代理
· CGLib动态代理
如上,通过静态代理实现,当出现码农工,农民工,搬砖工==的时候会有越来越多的,代理类出现,这不是一个好的idea。
所以需要一个代理类就够了,这时候,JDK提供的动态代理是不错的。
但是JDK提供的动态代理是基于有接口的实现类,当出现无实现接口的类时就不再适用了。
所以,CGLib则提供了这方面的实现。


静态代理实现:

public class CoderProxy implements Worker{

    private CoderImpl coderImpl;

    public CoderProxy(CoderImpl coderImpl){
        this.coderImpl = coderImpl;
    }
    @Override
    public void doJob(String doing) {
        before();
        coderImpl.doJob(doing);
        after();
    }

    private void before(){
        System.out.println("working before...");
    }

    private void after(){
        System.out.println("working after...");
    }

}

写一个test:

public class Test {
    public static void main(String[] args) {
        CoderProxy coderProxy = new CoderProxy(new CoderImpl());
        coderProxy.doJob("写代码");
    }
}

结果如下:
working before…
Your job is:写代码
working after…


JDK动态代理实现:

public class JDKDynamicProxy implements InvocationHandler {
    private Object target;

    public JDKDynamicProxy(Object target){
        this.target = target;
    }

    @SuppressWarnings("unchecked")
    public <T> T getProxy(){
        return (T) Proxy.newProxyInstance(
                target.getClass().getClassLoader(), 
                target.getClass().getInterfaces(), 
                this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        //注意此处的第一个参数并不是proxy
        Object object = method.invoke(target, args);
        after();
        return object;
    }

    private void before(){
        System.out.println("working before...");
    }

    private void after(){
        System.out.println("working after...");
    }
}

写一个test的main方法:

public static void main(String[] args) {
        Worker coder = new JDKDynamicProxy(new CoderImpl()).getProxy();
        coder.doJob("写代码");
    }

结果为:
working before…
Your job is:写代码
working after…


CGLib代理实现:
需要使用CGLib jar包

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CGLibProxy implements MethodInterceptor{
    //使用单例模式
    private static CGLibProxy instance = new CGLibProxy();

    private CGLibProxy(){}

    public static CGLibProxy getInstance(){
        return instance;
    }

    @SuppressWarnings("unchecked")
    public <T> T getProxy(Class<T> cls){
        return (T)Enhancer.create(cls, this);
    }

    @Override
    public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        before();
        Object obj = proxy.invokeSuper(target, args);
        after();
        return obj;
    }

    private void before(){
        System.out.println("working before...");
    }

    private void after(){
        System.out.println("working after...");
    }
}

测试一下:

public static void main(String[] args) {
        Worker coder = CGLibProxy.getInstance().getProxy(CoderImpl.class);
        coder.doJob("write code!");
    }

未完待续……


参考:《架构探险:从零开始写Java Web框架》(黄勇 著)

转载于:https://my.oschina.net/kevin1992/blog/913533

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值