Service层使用Spring获取Mapper对象
目前我们开发功能的流程中,在service层会手动创建SQLSession对象,并使用SQLSession对象获取Mapper接口的实例化对象,但是我们真正使用的是Mapper接口的对象,目前的代码编写方式极大的影响了开发效率,而且mybatis层和service 层之间的耦合性非常高
解决:
使用SpringIOC技术实现service层和mybatis层的解耦:说白了就是让Spring容器帮我们获取Mapper层接口的实例化 对象,我们直接从Spring容器中获取使用即可.
实现:
①导入SpringIOC的jar包
②在src下创建并配置Spring的配置文件
配置DataSource数据源的bean
配置SQLSessionFactory的工厂bean(DataSource的bean)
配置mapper扫描bean对象(SQLSessionFactory对象,扫 描路径)
③创建Spring容器对象,并获取Mapper接口的实例化对象完成数据库操作
Controller层使用Spring解耦service层
问题:
在业务层使用Spring容器对象获取Mapper接口实例化对象后实现了
service层和mybatis层的解耦,但是在controller层我们依然在Servlet
中直接创建Service对象,耦合性过高.
解决:
将service对象配置为bean对象,Servlet中从Spring容器中
获取Service对象,完成功能开发.
实现:
①在applicationcontext.xml文件中配置service的bean
②在servlet中的service方法中创建Spring容器对象
③在servlet中的service方法中从Spring容器中获取 service对象
④使用service对象完成功能处理
[1] MVC项目中使用SpringIOC解耦的代码优化
问题:
目前的整合中,tomcat服务在接收到请求后,会创建一个线程来处理请求,每个线程之间都是相互独立运行.流程如下:
①浏览器发起登录请求
②tomcat服务器获取请求,创建新的线程处理请求
③调用请求的Servlet对象中的service方法
假如10个用户发起登录请求,tomcat会创建10个线程处理请求.每个线程都需要调用UserServlet的service方法,而方法的调用依赖UserServlet的实例化对象,那么每个线程都创建一个UserServlet对象,还是UserServlet对象只有一个,但是被10个线程所共享使用呢?假如我们单线程操作,将UserServlet对象的service方法连续调用10此,代码如下:
UserServlet us=new UserServlet()
us.service();
us.service();
us.service();
us.service();
..........
而在此段代码中,我们完全可以声明10个线程,每个线程独立运行us.service().由此得出结论,在tomcat创建线程处理请求时,Servlet对象只会被创建一次,Servlet对象是多线程共享的.那么Servlet什么时候被创建呢?
默认在第一次请求的时候被创建,往后就不会再次重新创建了,如果配置了loadOnStartUp则在服务器启动的时候就会完成初始化创建.
④Servlet中的service方法被执行,service方法进栈.
然后创建Spring容器对象,内存堆中就会出现一个Spring容 器对象s1,而s1被创建的时候,会加载spring的配置文件,根 据配置文件创建对象(dataSource,factory,mapper,us).
⑤获取Spring容器中的业务层对象us
⑥调用us对象的登录业务方法
⑦登录业务方法进栈,又会创建一个新的Spring容器对象s2,
而s2被创建的时候,又加载解析Spring的配置文件,又创建 dataSource,factory,us,mapper的bean对象.
⑧在业务的登录方法中获取s2容器对象中的mapper对象完成 数据库操作,执行业务处理,登录业务方法处理完毕,返回结果 给controller的service方法,然后业务方法出栈.
⑨servlet的service方法获取到业务层的返回值后,继续处理,然后响应处理结果给浏览器,service方法结束,service方法出栈,请求处理完毕,线程销毁.
通过以上流程发现,目前的代码的结构,一个线程中会存在除Servlet对象以外10个对象,一旦高并发访问,会造成内存资源的极大的浪费,造成项目崩溃.
解决:
优化代码中的资源占比.