设计模式——代理模式(Proxy Pattern)+ Spring相关源码

文章目录

  • 一、代理模式
  • 二、例子
    • 2.1 菜鸟例子
      • 2.1.1 定义接口Image
      • 2.1.2 实现Image
      • 2.1.3 代理类ProxyImage
      • 2.1.4 使用
    • 2.2 JDK代理
    • 2.3 Spring——AspectJ静态代理使用
      • 2.3.1 Maven依赖
      • 2.3.2 定义切面注解
      • 2.3.3 启动静态代理
    • 2.4 Spring——AOP动态代理源码
      • 2.4.1 创建AOP代理对象的工厂类
      • 2.4.2 基于Cglib的AopProxy
      • 2.4.3 基于JDK的AopProxy
  • 三、其他设计模式

一、代理模式

类型: 结构型模式
目的: 提供一个代理对象,实现被代理对象控制访问功能增强

二、例子

2.1 菜鸟例子

2.1.1 定义接口Image

public interface Image {
   void display();
}

2.1.2 实现Image

public class RealImage implements Image {
 
   private String fileName;
 
   public RealImage(String fileName){
      this.fileName = fileName;
      loadFromDisk(fileName);
   }
 
   @Override
   public void display() {
      System.out.println("Displaying " + fileName);
   }
 
   private void loadFromDisk(String fileName){
      System.out.println("Loading " + fileName);
   }
}

2.1.3 代理类ProxyImage

public class ProxyImage implements Image{
 
   private RealImage realImage;
   private String fileName;
 
   public ProxyImage(String fileName){
      this.fileName = fileName;
   }
 
   @Override
   public void display() {
      if(realImage == null){
         realImage = new RealImage(fileName);
      }
      realImage.display();
   }
}

2.1.4 使用

public class ProxyPatternDemo {
   
   public static void main(String[] args) {
      Image image = new ProxyImage("test_10mb.jpg");
      // 图像将从磁盘加载
      image.display(); 
      System.out.println("");
      // 图像不需要从磁盘加载
      image.display();  
   }
}

2.2 JDK代理

以菜鸟教程为例子,改为JDK代理

public static void main(String[] args) throws Exception {
       //获取sayHello名称对于的Method类对象
       Method method =  Image.class.getMethod("display");
       //使用反射机制执行display方法。 核心Method(类中的方法)
       Image target = new RealImage("test_10mb.jpg");
       // 执行target 对象method(display)方法
       method.invoke(target);
}

2.3 Spring——AspectJ静态代理使用

AspectJ是一个面向切面编程(AOP)的框架,它可以用来实现静态代理。

2.3.1 Maven依赖

<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-aspectsartifactId>
    <version>${spring.version}version>
dependency>

2.3.2 定义切面注解

@Aspect
@Component
public class LoggingAspect {
 
    @Pointcut("execution(* com.example.demo.service..*.*(..))")
    private void serviceMethod() {}
 
    @Before("serviceMethod()")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("logBefore() is running!");
        System.out.println("hijacked : " + joinPoint.getSignature().getName());
        System.out.println("******");
    }
}

2.3.3 启动静态代理

@EnableAspectJAutoProxy
@Configuration
public class AppConfig {

}

2.4 Spring——AOP动态代理源码

2.4.1 创建AOP代理对象的工厂类

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (NativeDetector.inNativeImage() || !config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
            return new JdkDynamicAopProxy(config);
        } else {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
            } else {
                return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) && !ClassUtils.isLambdaClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
            }
        }
    }
}

2.4.2 基于Cglib的AopProxy

class ObjenesisCglibAopProxy extends CglibAopProxy {

    protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
        Class<?> proxyClass = enhancer.createClass();
        Object proxyInstance = null;
        if (objenesis.isWorthTrying()) {
            try {
                proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
            } catch (Throwable var7) {
                logger.debug("Unable to instantiate proxy using Objenesis, falling back to regular proxy construction", var7);
            }
        }

        if (proxyInstance == null) {
            try {
                Constructor<?> ctor = this.constructorArgs != null ? proxyClass.getDeclaredConstructor(this.constructorArgTypes) : proxyClass.getDeclaredConstructor();
                ReflectionUtils.makeAccessible(ctor);
                proxyInstance = this.constructorArgs != null ? ctor.newInstance(this.constructorArgs) : ctor.newInstance();
            } catch (Throwable var6) {
                throw new AopConfigException("Unable to instantiate proxy using Objenesis, and regular proxy instantiation via default constructor fails as well", var6);
            }
        }

        ((Factory)proxyInstance).setCallbacks(callbacks);
        return proxyInstance;
    }
}

2.4.3 基于JDK的AopProxy

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {

    public Object getProxy() {
        return this.getProxy(ClassUtils.getDefaultClassLoader());
    }

    public Object getProxy(@Nullable ClassLoader classLoader) {
        if (logger.isTraceEnabled()) {
            logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
        }

        return Proxy.newProxyInstance(this.determineClassLoader(classLoader), this.proxiedInterfaces, this);
    }



    @Nullable
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object oldProxy = null;
        boolean setProxyContext = false;
        TargetSource targetSource = this.advised.targetSource;
        Object target = null;

        Object var12;
        try {
            if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
                Boolean var18 = this.equals(args[0]);
                return var18;
            }

            if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
                Integer var17 = this.hashCode();
                return var17;
            }

            if (method.getDeclaringClass() == DecoratingProxy.class) {
                Class var16 = AopProxyUtils.ultimateTargetClass(this.advised);
                return var16;
            }

            Object retVal;
            if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) {
                retVal = AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
                return retVal;
            }

            if (this.advised.exposeProxy) {
                oldProxy = AopContext.setCurrentProxy(proxy);
                setProxyContext = true;
            }

            target = targetSource.getTarget();
            Class<?> targetClass = target != null ? target.getClass() : null;
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
            if (chain.isEmpty()) {
                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
            } else {
                MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                retVal = invocation.proceed();
            }

            Class<?> returnType = method.getReturnType();
            if (retVal != null && retVal == target && returnType != Object.class && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
                retVal = proxy;
            } else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
                throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
            }

            var12 = retVal;
        } finally {
            if (target != null && !targetSource.isStatic()) {
                targetSource.releaseTarget(target);
            }

            if (setProxyContext) {
                AopContext.setCurrentProxy(oldProxy);
            }

        }

        return var12;
    }


}


三、其他设计模式

创建型模式
结构型模式

  • 1、设计模式——装饰器模式(Decorator Pattern)+ Spring相关源码

行为型模式

  • 1、设计模式——访问者模式(Visitor Pattern)+ Spring相关源码
  • 2、设计模式——中介者模式(Mediator Pattern)+ JDK相关源码
  • 3、设计模式——策略模式(Strategy Pattern)+ Spring相关源码
  • 4、设计模式——状态模式(State Pattern)
  • 5、设计模式——命令模式(Command Pattern)+ Spring相关源码
  • 6、设计模式——观察者模式(Observer Pattern)+ Spring相关源码
  • 7、设计模式——备忘录模式(Memento Pattern)
  • 8、设计模式——模板方法模式(Template Pattern)+ Spring相关源码
  • 9、设计模式——迭代器模式(Iterator Pattern)+ Spring相关源码
  • 10、设计模式——责任链模式(Chain of Responsibility Pattern)+ Spring相关源码
  • 11、设计模式——解释器模式(Interpreter Pattern)+ Spring相关源码

你可能感兴趣的:(Programming,Concepts,设计模式,代理模式,spring,proxy,pattern,proxy,proxypattern,aop)