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

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

      

      

  • 相关阅读:
    机器学习(3)- 学习建议<误差出现如何解决?>
    机器学习(2)- 神经网络
    推荐系统(2)
    机器学习(1)- 概述&线性回归&逻辑回归&正则化
    朴素贝叶斯法(naive Bayes)
    约瑟夫环(java)
    AJAX请求详解 同步异步 GET和POST
    AJAX
    JspWriter与PrintWriter(转)
    Jsunit
  • 原文地址:https://www.cnblogs.com/LWLDD/p/8537476.html
Copyright © 2011-2022 走看看