美文网首页
spring基础(AOP)

spring基础(AOP)

作者: 鸡龙 | 来源:发表于2019-08-13 00:08 被阅读0次

    什么是AOP(面向切面)

    AOP可以说是OOP(面向对象)的补充和完善,OOP中有封装、继承、多态来建立一种对象层次结构,OOP允许你定义从上到下的关系,但却不适合定义从左到右的关系。例如日志功能。输出日志的代码往往水平地散步在所有对象层次中,但他却和核心功能毫不相关,这种散布到各处的代码被称为横切代码。

    而AOP却可以通过横切技术,将那些与业务无关,却为业务模块所共同调用的逻辑进行封装起来降低模块间的耦合度。

    AOP原理(代理)

    AOP实际上就是由目标类的代理类实现的。就像夹汉堡一样。目标类就是其中的一块肉。其他无关操作就是面包,代理类在特定切入点添加了增强处理是面包,并回调方法是肉。

    由于是代理实现AOP,而代理又分静态代理和动态代理。

    下面代码,如我们需要在调用service方法前后增加try catch,有两种方法,一种是直接在代码中添加try catch,一种是使用代理。由于一个方法可能会被调用多次,却每处都要进行修改,所以我们使用代理模式进行增加功能。

    public interface IService {
        public void service(String name )throws Exception;
    }
    
    public class ServiceImplA implements IService {
        @Override
        public void service(String name) throws Exception {
            System.out.println("ServiceImplA name" + name);
        }
    }
    
    

    1、静态代理

    静态代理实现很简单,就跟上面所说的,创建一个代理类,类中面包夹肉。但是这样使得每一个接口都需要写一个代理类,所以有了动态代理。

    public class ProxyServiceA implements IService {
        public IService service;
        public ProxyServiceA(IService service){
            super();
            this.service = service;
        }
        @Override
        public void service(String name) throws Exception {
            System.out.println("log start");
            try{
                service.service(name);
            }catch (Exception e){
                throw e;
            }
            System.out.println("log end");
        }
        public static void main(String []args) throws Exception {
            IService service = new ServiceImplA();
            service = new ProxyServiceA(service);
            service.service("zhjl");
        }
    }
    

    动态代理

    在java中的动态代理机制中,使用了Proxy类和实现了InvocationHandler接口。实现了invoke方法来实现动态代理。

    动态代理涉及到了之前反射中的描述方法,通过Proxy.newProxyInstance()生成的动态代理对象都会与实现InvocationHandler接口的对象关联。代理对象调用目标对象的方法时都会变成调用B中的invoke方法。

    public class DynaProxyServiceA implements InvocationHandler {
        private Object object;
        /**
         *   将目标对象关联到InvocationHandler接口,返回代理对象obj
         *   调用代理对象的方法时,都会自动调用invoke方法
         */
        public Object bind(Object object){
            this.object = object;
            Object obj = Proxy.newProxyInstance(
                    this.object.getClass().getClassLoader(),
                    this.object.getClass().getInterfaces(),
                    this);
            return obj;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object result;
            System.out.println("log start");
            try{
                result = method.invoke(this.object,args);
            }catch (Exception e){
                throw e;
            }
            System.out.println("log end");
            return result;
        }
        public static void main(String [] args) throws Exception {
            IService service = (IService)new DynaProxyServiceA()
                            .bind(new ServiceImplA());
            service.service("zhjl");
        }
    }
    

    与静态代理不同,动态代理不用再为每个接口手动创建代理类,只要该对象,获取到该对象的class实例,在增强处理中来通过class中的invoke来执行方法。

    相关文章

      网友评论

          本文标题:spring基础(AOP)

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