代理:给目标对象提供一个代理对象,并且由代理对象提供对目标对象的引用
代理的作用:功能的增强、控制访问:通过代理对象间接访问目标对象 ,以防直接访问目标对象产生不必要的风险。
首先提出一个问题:代理类如何知道它代理的是哪个类的哪个方法
有两种方式,第一种是用代理类来继承目标类,第二种是让目标类和代理类共同实现一个接口,然后将目标类的核心方法封装在接口当中,当代理类实现这个接口时,便可对目标类的方法进行重写增强。这样当用户使用时候,便可直接调用代理类里的方法即可。
这里我们选择用第二种方式来展示一下静态代理。我们以衣服制造为例
首先我们创建一个接口
public interface Clothes {
void clothes(String size);
}
我们创建一个目标类:衣服制造类,它继承了Clothes接口
public class ClothesFactory implements Clothes {
public void clothes(String size){
System.out.println("生产衣服的尺寸为:"+size);
}
}
我们再来创建ClothesFactory的代理类,也继承Clothes接口,我们可以在代理类里对clothes方法进行丰富拓展。
public class Proxy implements Clothes {
private ClothesFactory clothesFactory = new ClothesFactory();//代理对象
public void FrontService(){
System.out.println("衣服制造前的市场调研");
}
public void endService(){
System.out.println("制造衣服后的后置服务");
}
@Override
public void clothes(String size) {
FrontService();
clothesFactory.clothes(size);
endService();
}
}
我们创建一个测试类
public class Test {
public static void main(String[] args) {
Proxy proxy = new Proxy();
proxy.clothes("xxl");
}
}
运行结果:
我们通过代理类的对象调用了clothes方法。
下面我们来介绍下MyBatis的基本初始流程
我们知道使用mybatis的时候,一般是一个接口对应一个xml文件,项目启动时根据xml文件路径读取所有的xml信息。
我们通过I/O输入流的方式将xml主配置文件加载到内存中,同时将目标xml文件读取到内存(配置文件中映射了目标xml文件)
private InputStream in = null; private SqlSession session = null; private UserDao mapper = null;
in = Resources.getResourceAsStream("SqlMapConfig.xml");
然后根据主配置文件来创建一个SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
通过工厂来创建Session,Session是和数据库连接的最小分子
session = factory.openSession();
然后通过session来生成最终的代理对象
mapper = session.getMapper(UserDao.class);
由此方法生成的mapper就是动态代理对象。