zoukankan      html  css  js  c++  java
  • 动态代理的深入了解

    总结结构:

       静态代理模式的缺点:

          1、如果一个系统中有100Dao,则创建100个代理对象

          2、如果一个dao中有很多方法需要事务,则代理对象的方法中重复代码还是很多

          3、由第一点和第二点可以得出:proxy的重用性不强

    因为静态代理无法满足开发需求所以 引出动态代理

    动态代理模式:

       1、产生的代理对象和目标对象实现了共同的接口

           jdk动态代理

       2、代理对象是目标对象的子类

           hibernate: Person person = session.load(Person.class,1L);  javassisit

           spring:cglib动态代理

    jdk的动态代理:

       1、因为是用jdkAPI做到的

       2、代理对象是动态产生的

    cglib产生的代理类是目标类的子类

    注意事项:

        1、拦截器中invoke方法体的内容就是代理对象方法体的内容

        2、当客户端执行代理对象.方法时,进入到了拦截器的invoke方法体

        3、拦截器中invoke方法的method参数是在调用的时候赋值的

    aop:

       1、切面

            事务、日志、安全性框架、权限等都是切面  

       2、通知

          切面中的方法就是通知

       3、目标类

       4、切入点

             只有符合切入点,才能让通知和目标方法结合在一起

       5、织入:

             形成代理对象的方法的过程

             

     

    好处:

       事务、日志、安全性框架、权限、目标方法之间完全是松耦合的

    jdk的动态代理举例

    PersonDao.java

    1 package cn.itcast.jdkproxy.sh;
    2 
    3 public interface PersonDao {
    4     public void savePerson();
    5     public void updatePerson();
    6     public void deletePerson();
    7 }

    PersonDaoImpl.java

     1 package cn.itcast.jdkproxy.sh;
     2 
     3 public class PersonDaoImpl implements PersonDao{
     4     public void deletePerson() {
     5         System.out.println("delete person");
     6     }
     7     public void savePerson() {
     8         System.out.println("save person");
     9     }
    10     public void updatePerson() {
    11         System.out.println("update person");
    12     }
    13 }

    Transaction.java

     1 package cn.itcast.jdkproxy.sh;
     2 
     3 public class Transaction {
     4     public void beginTransaction(){
     5         System.out.println("开启事务 ");
     6     }
     7     public void commit(){
     8         System.out.println("事务提交");
     9     }
    10 }

    PersonInterceptor.java

     1 package cn.itcast.jdkproxy.sh;
     2 
     3 import java.lang.reflect.InvocationHandler;
     4 import java.lang.reflect.Method;
     5 
     6 /**
     7  * 拦截器
     8  * @author Think
     9  *   1、引入目标类
    10  *   2、引入事务
    11  *   3、通过构造函数给目标类和事务赋值
    12  *   4、填充invoke方法
    13  *
    14  */
    15 public class PersonInterceptor implements InvocationHandler{
    16     
    17     private Object target;//目标类
    18     private Transaction transaction;//引入事务
    19     
    20     public PersonInterceptor(Object target,Transaction transaction){
    21         this.target = target;
    22         this.transaction = transaction;
    23     }
    24     
    25 
    26     @Override
    27     public Object invoke(Object proxy, Method method, Object[] args)
    28             throws Throwable {
    29         // TODO Auto-generated method stub
    30         this.transaction.beginTransaction();
    31         method.invoke(this.target, args);//调用目标类的方法
    32         this.transaction.commit();
    33         return null;
    34     }
    35 
    36 }

    ProxyTest.java

     1 package cn.itcast.jdkproxy.sh;
     2 
     3 import java.lang.reflect.Proxy;
     4 
     5 import org.junit.Test;
     6 import org.springframework.context.ApplicationContext;
     7 import org.springframework.context.support.ClassPathXmlApplicationContext;
     8 
     9 public class ProxyTest {
    10     @Test
    11     public void test(){
    12         Object target = new PersonDaoImpl();
    13         Transaction transaction = new Transaction();
    14         PersonInterceptor interceptor = new PersonInterceptor(target, transaction);
    15         /**
    16          * 1、目标类的类加载器
    17          * 2、目标类实现的所有的接口
    18          * 3、拦截器
    19          */
    20         PersonDao personDao = (PersonDao)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), interceptor);
    21         personDao.deletePerson();
    22     }
    23 }

    实现jdk的动态代理,以上例子的改进可以在PersonInterceptor.java中添加成员函数

    private List<Interceptor> interceptors;

    然后让切面都继承 Interceptor接口,这个接口是自己定义的。

    改进版例子:

    1 package cn.itcast.jdkproxy.salary;
    2 
    3 public interface Interceptor {
    4     public void interceptor();
    5 }

    其它类:很多

     1 package cn.itcast.jdkproxy.salary;
     2 
     3 public class Logger implements Interceptor{
     4 
     5     @Override
     6     public void interceptor() {
     7         // TODO Auto-generated method stub
     8         System.out.println("logging");
     9     }
    10     
    11 }
     1 package cn.itcast.jdkproxy.salary;
     2 
     3 import java.lang.reflect.InvocationHandler;
     4 import java.lang.reflect.Method;
     5 import java.util.List;
     6 
     7 public class SalaryInterceptor implements InvocationHandler{
     8 
     9     
    10     private Object target;
    11     
    12     private List<Interceptor> interceptors;
    13     
    14     public SalaryInterceptor(Object target,List<Interceptor> interceptors){
    15         this.target = target;
    16         this.interceptors = interceptors;
    17     }
    18     
    19     @Override
    20     public Object invoke(Object proxy, Method method, Object[] args)
    21             throws Throwable {
    22         for(Interceptor interceptor:interceptors){
    23             interceptor.interceptor();
    24         }
    25         method.invoke(this.target, args);
    26         return null;
    27     }
    28 
    29 }

    客户端测试类

     1 package cn.itcast.jdkproxy.salary;
     2 
     3 import java.lang.reflect.Proxy;
     4 import java.util.ArrayList;
     5 import java.util.List;
     6 
     7 import org.junit.Test;
     8 
     9 public class SalaryTest {
    10     @Test
    11     public void test(){
    12         Object target = new SalaryManagerImpl();
    13         Logger logger = new Logger();
    14         Security security = new Security();
    15         Privilege privilege = new Privilege();
    16         List<Interceptor> interceptors = new ArrayList<Interceptor>();
    17         interceptors.add(logger);
    18         interceptors.add(security);
    19         interceptors.add(privilege);
    20         SalaryInterceptor interceptor = new SalaryInterceptor(target, interceptors);
    21         SalaryManager salaryManager = (SalaryManager)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), interceptor);
    22         salaryManager.showSalary();
    23     }
    24 }
  • 相关阅读:
    18、【opencv入门】形态学图像处理(一):开运算、闭运算、形态学梯度、顶帽、黑帽合辑
    17、【opencv入门】形态学图像处理(一):膨胀与腐蚀
    16、【opencv入门】创建Trackbar & 图像对比度、亮度值调整
    c++ 售货员的难题
    c++ 火柴棒等式
    c++ 素数圈
    c++ 分解数
    c++ 走迷宫
    c++ 二叉树遍历
    c++ n皇后问题
  • 原文地址:https://www.cnblogs.com/friends-wf/p/3783705.html
Copyright © 2011-2022 走看看