zoukankan      html  css  js  c++  java
  • 动态代理

    1   JDK动态代理    cglib动态代理

          

       先介绍jdk动态代理

       特点:代理目标对象必须有接口。

       实质:内存中构建出了接口的实现类。

       下面开始代码示例

       接口

      

    public interface Isomeservice {
        public void Some();
    }
    public class SomeServiceImpl implements Isomeservice {
        public void Some() {
            System.out.println("do some===============");
        }
    }

    以上为实现类 

     1 public class texr {
     2 
     3     public static void main(String[] args) {
     4 
     5         final Isomeservice se=new SomeServiceImpl();
     6 
     7 
     8         Isomeservice proxy=(Isomeservice) Proxy.newProxyInstance(se.getClass().getClassLoader(),
     9                 se.getClass().getInterfaces(), new InvocationHandler() {
    10                     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    11 
    12                         System.out.println("lalalaalal");
    13                         method.invoke(se,args);
    14                         return null;
    15                     }
    16                 });
    17 
    18 
    19 
    20         proxy.Some();
    21     }
    22 
    23 }
    View Code

    这个就是实现方法  。 

    lalalaalal
    do some===============

    以上是控制台,可以看出,我们实现了动态代理。  

    第二个开始讲 cglib 动态代理   

      特点:在一类型没有接口的情况下进行代理。

      实质:内存中在构建了目标类型的子类。

      对于不使用接口的业务类,无法使用JDK动态代理,cglib采用底层的字节码技术,可以为一个类创建子类。

      现在开始代码示例 

    public class SomeServiceImpl implements Isomeservice {
        public void Some() {
            System.out.println("do some===============");
        }
    }

    还是这个类 

    public class text {
        public static void main(String[] args) {
    
            final SomeServiceImpl some=new SomeServiceImpl();
    
            Enhancer enhancer=new Enhancer();
    
            enhancer.setSuperclass(some.getClass());
    
            enhancer.setCallback(new MethodInterceptor() {
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                    System.out.println("aaaaaaaa");
                    methodProxy.invoke(some,objects);
                    return null;
                }
            });
    
            SomeServiceImpl ss=  (SomeServiceImpl)enhancer.create();
    
            ss.Some();
    
    
    
    
        }
    }

    以上是实现了cglib动态代理,没有接口 

    aaaaaaaa
    do some===============

    控制台也可以看出,这个成功了 

    下面说下4种增强 

    先说环绕 

    以下开始代码示例

    public class Cdd {
    
        public  void some(){
    
            //int i=5/0;
            System.out.println("dfdfdfdfdfd");
    
        }
    
    }

    先给出环绕增强的 类

    public class Jack implements MethodInterceptor {
        public Object invoke(MethodInvocation methodInvocation) throws Throwable {
    
    
            System.out.println("=====aa");
    
    
            methodInvocation.proceed();
    
    
            System.out.println("==============bb");
    
            return null;
        }
    }
      methodInvocation.proceed(); 为隔开,前面的就为前置增强,后置的就为后置增强  
    

     

    下面开始看配置文件 

      <bean id="Cdd" class="cn.autowired.entity.Cdd"></bean>
    
      <bean id="Jack" class="cn.autowired.entity.Jack"></bean>
    
        <bean id="Proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
            <property name="target" ref="Cdd"></property>
            <property name="interceptorNames" value="Jack"></property>
        </bean>

    下面来说测试类

        @Test
        public void hh() {
            ApplicationContext context = new ClassPathXmlApplicationContext("application-04.xml");
    
            Cdd c = (Cdd) context.getBean("Proxy");
    
            try {
                c.some();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
    
        }

    以下运行 ,结果

    三月 10, 2018 9:27:20 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
    信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1517365b: startup date [Sat Mar 10 09:27:20 CST 2018]; root of context hierarchy
    三月 10, 2018 9:27:20 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    信息: Loading XML bean definitions from class path resource [application-04.xml]
    =====aa
    dfdfdfdfdfd
    ==============bb

    这样就实现了前后置增强 

     下面来讲异常增强 。 

    在使用类中出错来实现 

    public class Cdd {
    
        public  void some(){
    
            int i=5/0;
            System.out.println("dfdfdfdfdfd");
    
        }
    
    }

     这个运行时,铁定报错 

     现在来写异常增强 类 

     1  
     2 
     3 public class Expr implements ThrowsAdvice {
     4 
     5 public void afterThrowing(Exception e){
     6 
     7     System.out.println("网络异常");
     8 
     9 }
    10 
    11 
    12 }
    13  

    这个实现以下throwsAdvice就行,不过他没有要你必须要实现的方法  

    得自己手动写

    现在来看小配置 

    1  <bean id="Expr" class="cn.autowired.entity.Expr"></bean>
    2 
    3  <bean id="Proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    4         <property name="target" ref="Cdd"></property>
    5         <property name="interceptorNames" value="Expr"></property>
    6     </bean>

     现在来看测试类

        public void hh() {
            ApplicationContext context = new ClassPathXmlApplicationContext("application-04.xml");
    
            Cdd c = (Cdd) context.getBean("Proxy");
    
            try {
                c.some();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
    
        }

    就是这样,异常增强就实现了

    java.lang.ArithmeticException: / by zero
        at cn.autowired.entity.Cdd.some(Cdd.java:10)
        at cn.autowired.entity.Cdd$$FastClassBySpringCGLIB$$5f5b2599.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:125)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
        at cn.autowired.entity.Cdd$$EnhancerBySpringCGLIB$$1249e288.some(<generated>)
        at tt.hh(tt.java:269)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
        at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
        at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
        at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
        at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
    网络异常

    控制台也是铁定报错了 

    现在来说小配置的用法 

        <bean id="Proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
            <property name="target" ref="Cdd"></property>
            <property name="interceptorNames" value="Expr"></property>
        </bean>

    class,必须选对了,

     target 这一行,连接增强

       ref,为使用增强类的bean节点的id,

      interceptorNames 为增强类的节点 , value为增强类的bean节点的id 

    前后我就不说了 ,和之前写的博客一样 , 写出后 

    还是按照上面的来写 ,  

    1 为 bean节点   2 为 使用节点 

    现在来说 代理工厂 

    使用类依旧不变 

    Cdd  

    节点也就增加了 

        <bean id="Dg" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
            <property name="advice" ref="Befo"></property>
            <property name="mappedNames" value="some"></property>
         </bean>

    class中的东西是使用工厂的东西 

    1 advice  为使用的增强。

    2 mappedNames 为实用的方法。

    使用时 

    <bean id="Proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
            <property name="target" ref="Cdd"></property>
            <property name="interceptorNames" value="Dg"></property>
        </bean>

    把Value改成以上bean的id,这就好了 some为Cdd的方法

    现在看测试 

        @Test
        public void hh() {
            ApplicationContext context = new ClassPathXmlApplicationContext("application-04.xml");
    
            Cdd c = (Cdd) context.getBean("Proxy");
    
            try {
                c.some();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
    
        }
    三月 10, 2018 10:25:03 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
    信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1517365b: startup date [Sat Mar 10 10:25:03 CST 2018]; root of context hierarchy
    三月 10, 2018 10:25:03 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    信息: Loading XML bean definitions from class path resource [application-04.xml]
    aaaaaaaaa
    dfdfdfdfdfd

    现在看见控制台也就实现了这个

      

      

  • 相关阅读:
    LeetCode Path Sum II
    LeetCode Longest Palindromic Substring
    LeetCode Populating Next Right Pointers in Each Node II
    LeetCode Best Time to Buy and Sell Stock III
    LeetCode Binary Tree Maximum Path Sum
    LeetCode Find Peak Element
    LeetCode Maximum Product Subarray
    LeetCode Intersection of Two Linked Lists
    一天一个设计模式(1)——工厂模式
    PHP迭代器 Iterator
  • 原文地址:https://www.cnblogs.com/LWLDD/p/8537476.html
Copyright © 2011-2022 走看看