动态代理

代理某个类操作,该代理类需要实现跟被代理类同样的接口。

1.定义一个接口。

public interface IOper {

    public void run();
}

2.被代理类需要实现上面的接口

public class TrueOper implements IOper{

    public void run(){
        
        System.out.println("奔跑吧少年---");
    }
}

3.建立一个handle

 
  

    /** Processes a method invocation on a proxy instance and returns

 
  

     * the result.  This method will be invoked on an invocation handler

 
  

     * when a method is invoked on a proxy instance that it is

 
  

     * associated with.

   */

//代理类的每个方法会转到该handle的invoke方法
public
class OperHandler implements InvocationHandler{ private TrueOper oper; public OperHandler(TrueOper oper){ this.oper = oper; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("-------before--------"); Object obj = method.invoke(oper, args);

    
System.out.println("-------after----------");
     return obj;
    }

}

4.测试

public class TestProxy {

    public static void main(String[] args) {
        IOper proxyOper = (IOper)Proxy.newProxyInstance(IOper.class.getClassLoader(), new Class[]{IOper.class}, new OperHandler(new TrueOper()));
        
        proxyOper.run();
        
    }
}

原理:  在运行期间,proxyOper会动态生成一个class类,该类实现了IOper接口,代理类的每个方法都会调用OperHandler的invoker方法。

 

5: 一般该模式在系统架构中用到, 比如spring和mybatis结合时,用到sqlSession时,

SqlSessionTemplate有个例子

  public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType,
      PersistenceExceptionTranslator exceptionTranslator) {

    notNull(sqlSessionFactory, "Property 'sqlSessionFactory' is required");
    notNull(executorType, "Property 'executorType' is required");

    this.sqlSessionFactory = sqlSessionFactory;
    this.executorType = executorType;
    this.exceptionTranslator = exceptionTranslator;
    this.sqlSessionProxy = (SqlSession) newProxyInstance(
        SqlSessionFactory.class.getClassLoader(),
        new Class[] { SqlSession.class },
        new SqlSessionInterceptor());
  }

  /**
   * Proxy needed to route MyBatis method calls to the proper SqlSession got
   * from Spring's Transaction Manager
   * It also unwraps exceptions thrown by {@code Method#invoke(Object, Object...)} to
   * pass a {@code PersistenceException} to the {@code PersistenceExceptionTranslator}.
   */
  private class SqlSessionInterceptor implements InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      final SqlSession sqlSession = getSqlSession(
          SqlSessionTemplate.this.sqlSessionFactory,
          SqlSessionTemplate.this.executorType,
          SqlSessionTemplate.this.exceptionTranslator);
      try {
        Object result = method.invoke(sqlSession, args);
        if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
          // force commit even on non-dirty sessions because some databases require
          // a commit/rollback before calling close()
          sqlSession.commit(true);
        }
        return result;
      } catch (Throwable t) {
        Throwable unwrapped = unwrapThrowable(t);
        if (SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {
          Throwable translated = SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException) unwrapped);
          if (translated != null) {
            unwrapped = translated;
          }
        }
        throw unwrapped;
      } finally {
        closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
      }
    }
  }

 

 
 

 

转载于:https://www.cnblogs.com/shapeOfMyHeart/p/5038698.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值