Object-proxy

代理模式

故事扮演 提交于 2020-04-29 16:52:23
需求场景 我们引用了开源jar包,需要扩展。我们又不能直接改jar包,违反了开闭原则。通常我们使用代理模式,在中间加一层。软件行业有句话:”如果解决不了,就加一层“。 静态代理 步骤 第三方jar包中的目标类(即被代理类); 我们创建一个代理类,和目标类实现同样的接口,在内部调用目标类。 在代码中使用。 /** * 第三方jar包中的:目标类接口 * * @author lsh by 2020/4/29 */ public interface DoSthService { void doSth(); } /** * 第三方jar包中的:目标类实现类 * * @author lsh by 2020/4/29 */ public class DoSthServiceImpl implements DoSthService { @Override public void doSth() { System.out.println("被代理类 do sth"); } } /** * 静态代理类 * * @author lsh by 2020/4/29 */ public class DoSthServiceImplProxy implements DoSthService { @Override public void doSth() { // 加前置逻辑 System.out

Mybatis源码详解系列(三)--从Mapper接口开始看Mybatis的执行逻辑

£可爱£侵袭症+ 提交于 2020-04-24 12:53:17
Mybatis源码详解系列(三)--从Mapper接口开始看Mybatis的执行逻辑 简介 Mybatis 是一个持久层框架,它对 JDBC 进行了高级封装,使我们的代码中不会出现任何的 JDBC 代码,另外,它还通过 xml 或注解的方式将 sql 从 DAO/Repository 层中解耦出来,除了这些基本功能外,它还提供了动态 sql、延迟加载、缓存等功能。 相比 Hibernate,Mybatis 更面向数据库,可以灵活地对 sql 语句进行优化。 本文继续分析 Mybatis 的源码,第1点内容上一篇博客已经讲过,本文将针对 2 和 3 点继续分析: 加载配置、初始化SqlSessionFactory; 获取SqlSession和Mapper; 执行Mapper方法。 除了源码分析,本系列还包含 Mybatis 的详细使用方法、高级特性、生成器等,相关内容可以我的专栏 Mybatis。 注意,考虑可读性,文中部分源码经过删减。 隐藏在Mapper背后的东西 从使用者的角度来看,项目中使用 Mybatis 时,我们只需要定义Mapper接口和编写 xml,除此之外,不需要去使用 Mybatis 的其他东西。当我们调用了 Mapper 接口的方法,Mybatis 悄无声息地为我们完成参数设置、语句执行、结果映射等等工作,这真的是相当优秀的设计。 既然是分析源码

Java 动态代理机制

吃可爱长大的小学妹 提交于 2020-04-16 19:15:46
【推荐阅读】微服务还能火多久?>>> Java动态代理机制(参考上一篇的“基于xml文件的IOC配置案例”) 问题:大家有没有考虑过一件事呢?上面讲述的基于xml文件或者注解的IOC配置中持久层操作数据库的过程中没有事务的操作(完整的事务操作:开启事务、提交事务、回滚事务、释放资源)也能成功,那这是为何?(以转账的例子思索)原因很简单,就是每一次增删改查的操作都会获取一个连接,而相互之间没有任何的影响。那么如果在转账的过程中发生异常,数据库操作还会继续执行吗?答案是发生异常之前的数据库操作均可作数,异常之后的操作皆不可作数。这就不符合事务的第一特性——原子性(要么都成功,要么都失败) 为完善之前的代码,这里还需增加两个类——数据库连接类(需要和当前的线程绑定)和事务管理类 package com.mypro.utils; ​ import javax.sql.DataSource; import javax.xml.crypto.Data; import java.sql.Connection; ​ /** * 连接工具的类,用于从数据源获取一个连接,并实现和线程的绑定 */ public class ConnectionUtils { private ThreadLocal<Connection> tl = new ThreadLocal<> (); ​ private

浅析Java动态代理

倖福魔咒の 提交于 2020-04-05 20:47:45
Java的动态代理主要是指位于java.lang.reflect包下的Proxy类,在使用过程中会用到同一个包下的InvocationHandler接口。 1.Proxy类提供了个静态方法Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) ,用来生成代理对象: loader是目标类的类加载器,interfaces是目标类实现的接口(并不一定是它实现的所有接口,用Class<?>[]类型表示就可以了),h是InvocationHandler类型的一个对象。 2.InvocationHandler接口提供类一个方法Object invoke(Object proxy,Method method,Object[] args) throws Throwable,用来调用目标方法并提供新的功能: proxy是代理对象,method是目标方法,args是目标方法的参数列表。 所谓动态代理其实就是这样的一种对象:它是在程序运行时动态生成的对象,在生成它时你必须提供一组接口给它,然后该对象就宣称它实现了这些接口。你当然可以把该对象当作这些接口中的任何一个来用。当然,这其实就是一个代理对象,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler

SqlsessionTemplate线程安全解密

一世执手 提交于 2020-03-26 17:34:15
3 月,跳不动了?>>> SqlsessionTemplate线程安全解密 springboot中使用的是SqlsessionTemplate,而不是DefaultSqlsession,这个类是单例的,如何保证线程安全呢? 类图 源码解析 org.mybatis.spring.SqlSessionTemplate#selectList(java.lang.String),委托给代理 @Override public <E> List<E> selectList(String statement) { return this.sqlSessionProxy.<E> selectList(statement); } org.mybatis.spring.SqlSessionTemplate.SqlSessionInterceptor#invoke,代理类核心方法 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 获取Sqlsession SqlSession sqlSession = getSqlSession( SqlSessionTemplate.this.sqlSessionFactory, SqlSessionTemplate.this

MapperFactoryBean产生代理原理

最后都变了- 提交于 2020-03-26 11:16:32
3 月,跳不动了?>>> MapperFactoryBean产生代理原理 类图 流程 这个类实现了FactoryBean,spring会通过 org.mybatis.spring.mapper.MapperFactoryBean#getObject 来产生bean对象。 @Override public T getObject() throws Exception { return getSqlSession().getMapper(this.mapperInterface); } 委托sqlSession来产生mapper。org.apache.ibatis.binding.MapperRegistry#getMapper。 public <T> T getMapper(Class<T> type, SqlSession sqlSession) { final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type); if (mapperProxyFactory == null) { throw new BindingException("Type " + type + " is not known to the MapperRegistry."); }

面试刷题6:反射和动态代理是什么?

房东的猫 提交于 2020-03-24 19:43:32
3 月,跳不动了?>>> 反射和动态代理是什么? 反射是java提供的一种自省能力,可以在运行时创建类的实例,访问成员变量,方法。 动态代理是程序在运行时构建代理对象动态动用方法。 反射和动态代理是第三方框架进行封装的基础。 反射 程序提供的一种自省能力,可以在运行时操作类和对象。 提供的核心类如下: Class: 获取类的定义 Field : 获取申明的属性 Method: 获取申明的方法 Constructor : 构造新对象 需要注意setAccessble(Boolean)方法; 可以修改反射的相关对象的访问控制权限; 比如: ORM框架自动生成set,get方法;<br />某些API的private成员和方法的操作,定制API的功能; 动态代理 运行时自动构建代理,处理方法调用; 实现方式有: jdkProxy, cglib; 对比项目 说明 JdkProxy 1.代码简单<br />2,无额外依赖<br />3,可以跟随jdk平滑升级 Cglib 1,性能优<br />2,不用实现额外接口<br />3,只关心操作的类 常见应用:RPC调用,AOP 下面的代码是使用jdkProxy的例子: public class MyDynamicProxy { public static void main (String[] args) { HelloImpl hello =

Java代理(Proxy)

北城以北 提交于 2019-12-04 06:43:46
利用 代理 可以在 运行时 创建一个 实现了一组给定接口 的新的实现类。 假设有一个表示接口的Class对象,它的确切类型在编译时无法知道,要想在运行时构造一个实现了该接口的类,就需要使用newInstance方法或者反射找到构造器,很复杂,很麻烦。那么代理可以解决这个问题! 代理需要提供一个实现了InvocationHandler接口的调用处理器,在这个接口中只定义了一个方法: public interface InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; } 这样无论何时调用代理对象的方法,调用处理器的invoke方法都会被调用,并向其传递Method对象和原始的参数,调用处理器必须在invoke方法中给出处理调用的方式。 创建代理对象 创建一个代理对象,需要使用Proxy类的newProxyInstance方法: public class Proxy implements java.io.Serializable { // more code ... public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,

mybaits sqlSession 源码解读

戏子无情 提交于 2019-12-01 05:15:44
SqlSession org.apache.ibatis.session.SqlSession 是 mybatis 操作sql、 获取mapper、处理事务的基本单元。一般意义上我们运用mybatis 都是在操作 sqlSession 类图如下: org.apache.ibatis.session.defaults.DefaultSqlSession 默认实现。 DefaultSqlSession 的初始化过程 SqlSessionFactoryBuilder --> DefaultSqlSessionFactory --> SqlSession SqlSession模式一 所有 <T> T selectOne 、 <E> List<E> selectList 均由 <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) 实现。源码: [@Override](https://my.oschina.net/u/1162528) public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) { try { MappedStatement ms = configuration