Spring AOP之静态代理

本文参考自:https://www.cnblogs.com/fingerboy/p/5335328.html  

       在学习Spring框架的时候,由一个重要的思想 就是AOP,面向切面遍程,利用AOP的思想结合Spring的一些API可以实现核心业务和辅助业务的分离,也就是在执行核心业务的时候,将辅助业务加进来。而辅助业务利用日志控制权限一般是一些公共业务,这样就实现了两者的分离。这么做的好处,可以是核心业务更加纯粹,辅助业务也能得到更好的复用。

为什么要代理。

        打一个比方,假如我想学习,那么我学习之前必须把书包拿过来,把书包打开,准备好纸笔,开始学习,学习完之后把书放进去,整理书包。明显学习是我的纯粹业务,其他术语公共业务。我们将拿书包,取书,整理书包的事情交给妈妈做,这里的妈妈就是代理。

 

 联想一下,在刚开始接程数据库的时候,我们需要打开连接,执行操作,关闭连接。这么做让我们的业务代码遍得不纯粹。这就是传统开发中存在的问题。

package com.wang.proxy;
/**
 * 简单业务层接口,只有一个save方法
 */
interface UserService{
    public void saveUser();
}

/**
 * 代理类
 */
class UserServiceProxy implements UserService{

    private UserService userService;
    
    public UserServiceProxy(UserService userService) {
        super();
        this.userService = userService;
    }

    public void open(){
        System.out.println("1:打开数据库连接");
    }
    public void close(){
        System.out.println("3:关闭数据库连接");
    }
    @Override
    public void saveUser() {
        this.open();
        userService.saveUser();
        this.close();
    }
    
}

/**
 * 业务层实现类,实现save方法
 */
class UserServiceImpl implements UserService{

    @Override
    public void saveUser() {
        System.out.println("2:保存用户信息");
    }
    
}
/**
 * 测试类
 */
public class TestProxy {
    
    public static void main(String[] args) {
        UserService userService =new UserServiceProxy(new UserServiceImpl());
        userService.saveUser();
    }
}

上边的例子就是静态代理,静态代理我们必须为所有的代理,单独协议个代理类,于是就有了更加抽象的动态代理,动态代理是利用反射来实现的

  如果要使用动态代理,必须要实现InvocationHandler接口,  有如下方法

  Object  invoke(Object proxy, Method method, Object[] args)    :在代理实例上处理方法调

    proxy ,表示需要代理的对象

    method 表示要操作的方法。

    args method 方法要传入的参数

如果想要让代理设计真正可用,我们还必须要由一个代理类对象产生,代理类创建的过程如下:

public static Object newProxyInstance(ClassLoader loader,
                                       Class<?>[] interfaces,
                                       InvocationHandler h)
                                  throws IllegalArgumentException
该方法返回一个指定的代理实例。
  loader:dinginess代理的类加载器
  interface ,代理类要实现的接口列表
  h 指派方法调用的处理程序

动态代理的代码如下

class ServiceProxy implements InvocationHandler {

    private Object target=null;//保存真实业务对象
    /**
     * 返回动态代理类的对象,这样用户才可以利用代理类对象去操作真实对象
     * @param obj  包含有真实业务实现的对象
     * @return   返回代理对象
     */
    public Object getProxy(Object obj) {
        this.target=obj;//保存真实业务对象
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj
                .getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        Object result=method.invoke(target, args);//通过反射调用真实业务对象的业务方法,并且返回
        return result;
    }

}
public class TestProxy {

    public static void main(String[] args) {
            UserService service=(UserService) new ServiceProxy().getProxy(new UserServiceImpl());
            service.saveUser();
    }
}

 

posted @ 2020-05-08 11:07  dousil  阅读(339)  评论(0编辑  收藏  举报