创建动态代理

  public  class DynamicProxy
    {
      public DynamicProxy(Uri uri)
      {
          this.uri = uri;
          ServicePointManager.ServerCertificateValidationCallback = CheckValidationResult;
      }

      private Uri uri = null;
      public string serviceName;
      public Assembly proxyAssembly;
      private ServiceDescription serviceDesc;
       public ServiceDescription ServiceDescription 
      {
          get {
              if (serviceDesc == null)
              {
                  serviceDesc = GetServiceDescription();
              }
              return serviceDesc;
          }
      }
      private ServiceDescription GetServiceDescription()
      {
          if (uri == null) return null;

          WebRequest webReq = WebRequest.Create(uri);
          Stream reqStrm = webReq.GetResponse().GetResponseStream();
          return ServiceDescription.Read(reqStrm);
      }
      public bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
      {
          if ((sslPolicyErrors == SslPolicyErrors.None) ||
          ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) == SslPolicyErrors.RemoteCertificateChainErrors) ||
          ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch) ||
          ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) == SslPolicyErrors.RemoteCertificateNotAvailable))
              return true;

          return false;
      }
      public MethodInfo[] GetWebMethods()
      {
          serviceName = this.ServiceDescription.Services[0].Name;

          if (proxyAssembly == null)
          {
              proxyAssembly = GenerateProxyAssembly();
              if (proxyAssembly == null)
                  throw new InvalidOperationException("Unable to generate the proxy assembly.");
          }

          //Use reflection to find the methods on the service requested by the user
          Type service = proxyAssembly.GetType(serviceName);
          return service.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.IgnoreCase |
                         BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public);
      }
      private Assembly GenerateProxyAssembly()
      {
          //Import the information about the service
          ServiceDescriptionImporter servImport = new ServiceDescriptionImporter();
          servImport.AddServiceDescription(this.ServiceDescription, String.Empty, String.Empty);
          servImport.ProtocolName = "Soap";
          servImport.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties;

          //Set up to generate the code
          CodeNamespace ns = new CodeNamespace();
          CodeCompileUnit ccu = new CodeCompileUnit();
          ccu.Namespaces.Add(ns);
          ServiceDescriptionImportWarnings warnings = servImport.Import(ns, ccu);
          //If we didn't find any methods there will be nothing to call later so just stop now.
          if ((warnings == ServiceDescriptionImportWarnings.NoCodeGenerated) ||
          (warnings == ServiceDescriptionImportWarnings.NoMethodsGenerated)) return null;

          CSharpCodeProvider prov = new CSharpCodeProvider();

          //Generate the code
          StringWriter sw = new StringWriter(CultureInfo.CurrentCulture);
          prov.GenerateCodeFromNamespace(ns, sw, null);

          //Create the assembly
          CompilerParameters param = new CompilerParameters(new String[] { "System.dll", "System.Xml.dll", "System.Web.Services.dll", "System.Data.dll" });
          param.GenerateExecutable = false;
          param.GenerateInMemory = false;
          param.TreatWarningsAsErrors = false;
          param.WarningLevel = 4;
          CompilerResults results = new CompilerResults(null);
          results = prov.CompileAssemblyFromSource(param, sw.ToString());
          return results.CompiledAssembly;
      }
    }

### Spring框架中动态代理如何替换方法执行逻辑 Spring 框架通过 **AOP(面向切面编程)** 实现了对目标方法的增强,其核心机制是利用 **动态代理技术** 来拦截和替换原始方法调用逻辑。在创建代理对象之后,Spring 会将原本直接调用的方法逻辑替换成一个包含增强逻辑的代理逻辑链。 #### JDK 动态代理与 CGLIB 动态代理的差异 Spring AOP 支持两种代理方式:JDK 动态代理 和 CGLIB 动态代理。前者适用于实现了接口的类,后者适用于没有实现接口的类[^2]。 - **JDK 动态代理**:基于 `java.lang.reflect.Proxy` 创建代理对象,所有的方法调用都会被转发到 `InvocationHandler` 的 `invoke` 方法中。 - **CGLIB 动态代理**:通过继承目标类生成子类,并重写目标方法以插入增强逻辑。 在这两种方式中,Spring 都会将目标方法的调用逻辑替换为一个拦截器链,从而实现增强逻辑的插入。 #### 方法调用的替换过程 当 Spring 创建了一个代理对象后,实际调用目标方法的过程如下: 1. 调用代理对象的方法时,控制权会转移到代理内部的拦截器链。 2. 对于 **JDK 动态代理**,调用进入 `JdkDynamicAopProxy.invoke()` 方法。 3. 对于 **CGLIB 动态代理**,调用进入 `DynamicAdvisedInterceptor.intercept()` 方法。 4. 在拦截器中,Spring 会根据配置的通知类型(如 `@Before`, `@After`, `@Around`)构建责任链式调用结构。 5. 增强逻辑依次执行,最后再调用原始的目标方法(如果未被环绕通知阻断)[^2]。 #### 示例代码:JDK 动态代理的调用流程 ```java public class JdkDynamicAopProxy implements InvocationHandler { private final AdvisedSupport advised; public JdkDynamicAopProxy(AdvisedSupport config) { this.advised = config; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 获取拦截器链并执行增强逻辑 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); if (chain.isEmpty()) { // 如果没有增强,则直接调用目标方法 return method.invoke(target, args); } else { // 否则使用责任链模式执行增强逻辑 MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); return invocation.proceed(); } } } ``` 上述代码展示了 `JdkDynamicAopProxy` 是如何将原始方法调用替换为带有增强逻辑的代理逻辑的。拦截器链中的每个元素都会按照顺序执行,最终才调用目标方法[^2]。 #### 自调用问题的限制 由于 Spring AOP 的代理机制是基于外部调用的,因此对于 **自调用(self-invocation)** 场景(即一个 Bean 内部的方法调用自己的另一个方法)不会触发增强逻辑。这是因为 Spring 的代理对象是在容器中创建的,只有外部通过代理对象发起的方法调用才会经过增强逻辑;而内部方法调用仍然是直接作用于目标对象本身,绕过了代理层[^1]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值