zoukankan      html  css  js  c++  java
  • Spring AOP 原理

    静态代理

    public class ProxyDemo {
        public static void main(String[] args) {
            RealImage realImage = new RealImage();
            ProxyImage proxyImage = new ProxyImage(realImage);
            proxyImage.doSomething();
        }
    }
    
    interface Image {
        void doSomething();
    }
    
    class RealImage implements Image {
    
        @Override
        public void doSomething() {
            System.out.println("Real image");
        }
    }
    
    class ProxyImage implements Image {
        private RealImage realImage;
    
        public ProxyImage(RealImage realImage) {
            this.realImage = realImage;
        }
    
        @Override
        public void doSomething() {
            System.out.println("proxy start");
            realImage.doSomething();
            System.out.println("proxy end");
        }
    }

    打印结果:

    proxy start
    Real image
    proxy end

    JDK 动态代理(基于接口)

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class ProxyDemo {
        public static void main(String[] args) {
            Target target = new TargetImpl();
            TargetIH targetIH = new TargetIH(target);
            Class<?> clazz = target.getClass();
            Target proxyInstance = (Target) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), targetIH);
            proxyInstance.doSomething();
            proxyInstance.doSomethingElse();
        }
    }
    
    interface Target {
        void doSomething();
        void doSomethingElse();
    }
    
    class TargetImpl implements Target {
    
        @Override
        public void doSomething() {
            System.out.println("TargetImpl doSomething");
        }
        
        @Override
        public void doSomethingElse() {
            System.out.println("TargetImpl doSomethingElse");
        }
    }
    
    class TargetIH implements InvocationHandler {
        private Object target;
    
        public TargetIH(Object target) {
            this.target = target;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) {
            System.out.println("proxy start");
            Object result = null;
            try {
                result = method.invoke(target, args);
            } catch (Exception e) {
                // do something
            }
            System.out.println("proxy end");
            return result;
        }
    }

    打印:

    proxy start
    TargetImpl doSomething
    proxy end
    proxy start
    TargetImpl doSomethingElse
    proxy end

    CGLIB

    CGLIB (Byte Code Generation Library is high level API to generate and transform Java byte code. It is used by AOP, testing, data access frameworks to generate dynamic proxy objects and intercept field access)动态代理,不需要有接口

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.2.5</version>
    </dependency>
    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 ProxyDemo {
        public static void main(String[] args) {
            
            TargetMI interceptor = new TargetMI();
            Enhancer e = new Enhancer();
            e.setSuperclass(Target.class);
            e.setCallback(interceptor);
            Target proxyInstance = (Target) e.create();
            proxyInstance.doSomething();
        }
    }
    
    class Target {
        public void doSomething() {
            System.out.println("doSomething");
        }
    }
    
    class TargetMI implements MethodInterceptor {
    
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println("proxy start");
            Object retValFromSuper = proxy.invokeSuper(obj, args);
            System.out.println("proxy end");
            return retValFromSuper;
        }
    }

    打印:

    proxy start
    doSomething
    proxy end

    Spring AOP

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.10</version>
        </dependency>
    </dependencies>
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
    
    <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
    <context:annotation-config />
    <context:component-scan base-package="cn.zno.*" />
    
    </beans>
    package cn.zno.foo;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.stereotype.Component;
    
    public class ProxyDemo {
    
        public static void main(String[] args) {
            @SuppressWarnings("resource")
            ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
            Target target = (Target) ctx.getBean(Target.class);
            target.doSomething();
            target.doSomethingElse();
        }
    }
    
    interface Target {
        public void doSomething();
        public void doSomethingElse();
    }
    
    @Component
    class TargetImpl implements Target {
    
        @Override
        public void doSomething() {
            System.out.println("doSomething");
        }
    
        @Override
        public void doSomethingElse() {
            System.out.println("doSomethingElse");
        }
    }
    
    @Component // 需要注册到bean工厂,否则不会生效
    @Aspect // 需要配置Spring AOP
    class TargetInterceptor {
        
        @Pointcut("execution(* doSomething(..)) || execution(* doSomethingElse(..))") // the pointcut(target method) signature
        private void anysdf() {
            System.out.println("pointcut signature");
        }
    
        @Before(value = "anysdf()")
        public void before(JoinPoint joinPoint) {
            System.out.println("Before");
        }
    
        @After("anysdf()")
        public void after() {
            System.out.println("After");
        }
    }

    打印:

    Before
    doSomething
    After
    Before
    doSomethingElse
    After

  • 相关阅读:
    循环语句
    流程控制
    特殊的赋值运算符
    位运算符
    运算符
    八种基本类型
    cmd基础命令
    springboot项目部署到tomcat步骤以及常见问题
    【算法问题】如何实现大整数相加
    【算法问题】删除k个数字后的最小值
  • 原文地址:https://www.cnblogs.com/zno2/p/7522134.html
Copyright © 2011-2022 走看看