Spring原理说明:
// 方式零:就在实现类中改,用哪个改哪个
// new出来的,耦合性太强,依赖于具体的实现类,如果我具体的实现类变了,那么这里的接口代码也得跟着变,这样不好。
// private IUserDao dao = new IUserDaoImpl();
// private IUserDao dao = new IUserDaoImplForOracle();
// 方式一:不在实现类中修改,在工厂类中改forName的参数
// private IUserDao dao = BeanFactory.newInstance().getUserDao();
// 方式二:不在工厂类中修改,在配置文件中修改,拿到的是普通对象,是我自己去生成
// private IUserDao dao = (IUserDao) BeanFactory.newInstance().getDao("USERDAO");
// private IUserDao dao1 = (IStudentDao) BeanFactory.newInstance().getDao("STUDENT");
// 方式三:不在工厂类中修改,在配置文件中修改,拿到的是代理对象,让代理对象帮我生成,我去这是最懒的方式啊!
private IUserDao dao = (IUserDao) BeanFactory.newInstance().getProxyDao("USERDAO");
// 每次想用这个代理类对象的时候,每次都会生成,但是IUserDao对象,我只需要getXxx()生成一次就够了,以后就是调用里面的方法了,并没有赋值操作。
// 回想我们为什么使用数据库连接池呢?答:因为与数据库连接是最耗时的,即getConnection。
// 我们使用数据库连接池的目的就是把这个最耗时的操作放在最开始的时候,就是服务器启动的时候,因为服务器启动的时候,大家都在等待。
// 同理,在服务器启动的时候,那我们能不能把生成代理对象的操作放在某个地方放好,让他们先等着?答:当然能啊!我们可以把他们放在一个全局的域中(一个Map里)。
// 为什么是“放”呢?答:因为只有取操作,没有赋值操作。
// 怎么做呢?答:那就初始化一个容器(一个Map容器)。
// 我怎么知道你启动了呢?即什么时候初始化一个容器呢?答:使用服务器监听器.
// ServletContextListener,这个监听器监听application域的创建和销毁,因为服务器一启动,应用就被加载。监听器就可以监听到。
// 那Spring做的是什么事呢?答:就是在服务器启动的时候,给你初始化一个这样的容器,把所有要用的代理对象都扔到里面,你想用的话,就从里面取出就行。
// 所以Spring在web.xml中的就是配置实现了一个实现了ServletContextListener接口的监听器。
下面这张图片里面的知识非常重要,对理解Spring原理很有帮助,请下载观看: