美文网首页
Maven项目&Spring AOP基础(一)

Maven项目&Spring AOP基础(一)

作者: 乘风破浪的姐姐 | 来源:发表于2021-12-31 14:40 被阅读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了一个用户。
    

    相关文章

      网友评论

          本文标题:Maven项目&Spring AOP基础(一)

          本文链接:https://www.haomeiwen.com/subject/duyiqrtx.html