Maven项目&Spring AOP基础(一)

2021-12-31  本文已影响0人  乘风破浪的姐姐

Spring AOP的底层机制就是动态代理。而代理模式又分为:静态代理、动态代理。

静态代理的角色分为:
抽象角色 : 一般使用接口或者抽象类来实现,例如:租房这个动作
真实角色 : 被代理的角色,例如:房东
代理角色 : 代理真实角色 ; 代理真实角色后 , 一般会做一些附属的操作 ,例如:中介
客户 : 使用代理角色来进行一些操作 ,例如:要租房的房客

代码实现1
抽象角色:Rent.class

public interface Rent {
    void rentHouse();
}

真实角色:Host .class

public class Host implements Rent {
    public void rentHouse() {
        System.out.println("我的房子要出租。");
    }
}

代理角色:Proxy.class

public class Proxy implements Rent {
    Host host ;

    public Proxy(Host host) {
        this.host = host;
    }
//租房
    public void rentHouse() {
        host.rentHouse();
    }
//看房
   public void seeHouse(){
       System.out.println("带房客看房");
  }
   //收中介费
   public void fare(){
       System.out.println("收中介费");
  }
}

客户 :Client.class

public class Client {
    public static void main(String[] args) {
      //房东要租房
        Host host = new Host();
      //中介帮助房东
        Proxy proxy = new Proxy(host);
       //房客找中介!
       proxy.rentHouse();
       //中介带房客看房
       proxy.seeHouse();
      //中介收中介费
       proxy.fare();
    }
}

代码实现2
抽象角色:业务接口UserService

public interface UserService {
    void add();
    void update();
    void query();
    void delete();
}

真实角色:实现接口完成这些增删改查操作UserServiceImpl

public class UserServiceImpl implements UserService {
    public void add() {
        System.out.println("新增用户");
    }

    public void update() {
        System.out.println("修改用户");
    }

    public void query() {
        System.out.println("查询用户");
    }

    public void delete() {
        System.out.println("删除用户");
    }
}

现需要给上述每个实现方法中都增加打印日志的功能。
如果直接在每个方法中增加打印日志的代码,就改变了原有的业务逻辑,那么在不改变原有业务的情况下,就需要使用到代理角色来实现。
代理角色:设置一个代理类来处理日志UserServiceProxyImpl

public class UserServiceProxyImpl implements  UserService {

    UserServiceImpl userServiceImpl ;

    public UserServiceProxyImpl(UserServiceImpl userServiceImpl) {
        this.userServiceImpl = userServiceImpl;
    }

    public void add() {
        log("add");
        userServiceImpl.add();
    }

    public void update() {
        log("update");
        userServiceImpl.update();
    }

    public void query() {
        log("query");
        userServiceImpl.query();
    }

    public void delete() {
        log("delete");
        userServiceImpl.delete();

    }

    public void log(String msg){
        System.out.println(msg+"了一个用户");
    }
}

客户:测试访问类 UserServiceTest

public class UserServiceTest {
    public static void main(String[] args) {
        UserServiceImpl userService = new UserServiceImpl();
        UserServiceProxyImpl userServiceProxy = new UserServiceProxyImpl(userService);
        userServiceProxy.add();
    }
}

从上述代码可以看出,AOP中最核心的思想就是不改变原来的代码的情况下,实现了对原有功能的增强。

动态代理
动态代理的角色和静态代理的一样 .
动态代理的代理类是动态生成的 . 静态代理的代理类是提前写好的
动态代理分为两类 : 一类是基于接口动态代理 , 一类是基于类的动态代理。
以下通过JDK的原生代码来实现,JDK的动态代理需要了解两个类
核心 : InvocationHandler 和Proxy

改造上述两个示例。
代码实现1
抽象角色:Rent

public interface Rent {
    void rentHouse();
}

真实角色:RealHost

public class RealHost implements Rent
{
    @Override
    public void rent()
    {
        System.out.println("I want to rent my house");
    }
}

代理角色:DynamicProxy

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DynamicProxy implements InvocationHandler
{
    // 这个就是要代理的真实对象(例如:租房)
    private Object realObj;

    //    构造方法,给要代理的真实对象赋初值
    public DynamicProxy(Object obj)
    {
        this.realObj = obj;
    }

    //生成代理类,重点是第二个参数,获取要代理的抽象角色!之前都是一个角色,现在可以代理一类角色
    /*
     * 通过Proxy的newProxyInstance方法来创建的代理对象,其三个参数
     * 第一个参数 handler.getClass().getClassLoader() , 这里使用handler这个类的ClassLoader对象来加载我们的代理对象
     * 第二个参数 renObject.getClass().getInterfaces(), 这里为代理对象提供的接口是真实对象所调用的接口,表示要代理的是该真实对象,这样就能调用这组接口中的方法了
     * 第三个参数 handler, 这里将这个代理对象关联到了上方的 InvocationHandler 这个对象上
     */

    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                realObj.getClass().getInterfaces(),this);
    }


    @Override
    public Object invoke(Object object, Method method, Object[] args)
            throws Throwable
    {
        //在代理真实对象前可以添加一些自己的操作
        System.out.println("before rent house");

        //当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
        method.invoke(realObj, args);

        //在代理真实对象后也可以添加一些自己的操作
        System.out.println("after rent house");

        return null;
    }

客户:Client

public class Client {
    public static void main(String[] args)
    {
        //要代理的真实对象
        Rent realHost = new RealHost();

        //要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法的
        DynamicProxy handler = new DynamicProxy(realHost);
        Rent proxy = (Rent) handler.getProxy();
        proxy.rent();
    }
}

输出结果:

before rent house
I want to rent my house
after rent house

代码实现2
抽象角色:业务接口UserService

public interface UserService {
    void add();
    void update();
    void query();
    void delete();
}

真实角色:实现增删改查操作UserServiceImpl

public class UserServiceImpl implements UserService {
    public void add() {
        System.out.println("新增用户");
    }

    public void update() {
        System.out.println("修改用户");

    }

    public void query() {
        System.out.println("查询用户");

    }

    public void delete() {
        System.out.println("删除用户");

    }
}

代理角色:DynamicProxyHandler

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DynamicProxyHandler implements InvocationHandler {
    private Object object;

    public DynamicProxyHandler(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        method.invoke(object,args);
        log(method.getName());
        return null;
    }


    public Object getProxyObj(){
        ClassLoader classLoader = DynamicProxyHandler.class.getClassLoader();
        Class<?>[] interfaces = object.getClass().getInterfaces();
        return Proxy.newProxyInstance(classLoader,interfaces,this);
    }

    public void log(String msg){
        System.out.println(msg+"了一个用户。");
    }
}

客户:测试访问类 UserServiceTest

public class UserServiceTest {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();

        DynamicProxyHandler userServiceProxy = new DynamicProxyHandler(userService);
        UserService proxyObj = (UserService) userServiceProxy.getProxyObj();
        proxyObj.add();
        proxyObj.delete();
        proxyObj.update();
        proxyObj.query();
    }
}

输出结果:

新增用户
add了一个用户。
删除用户
delete了一个用户。
修改用户
update了一个用户。
查询用户
query了一个用户。
上一篇下一篇

猜你喜欢

热点阅读