在Java Web项目里实现IOC(不使用框架,自己通过代码实现)
2013-04-14 22:10
603 查看
一:IOC的好处
有的项目在管理DAO的时候会抽象出一个interface,如ArticleDao;然后去做一些他的实现:如ArticleDaoForDb2或者ArticleDaoForOracle。这样在Servlet里面new一个ArticleDao可以写成:
这种做法带来的问题:项目一大,就有很多dao类,如ContentDao,PersonDao等等等。如果有一天要将他们的实现从ForOracle改成ForDb2,这样在代码里面的改动就会很大。
IOC:控制翻转,本来需要在代码里面将某个类的具体实现new出来的,现在不用new了,只需要在配置文件做一下配置。这样一来,如果我们想将dao的实现从ForOracle改成ForDb2。只需要在一个配置文件里面改就行了,不用再在很多个的servlet类里面一个个的改。
个人认为IOC适用于一些大项目,对于一些小项目,本身就只有一个实现,就没有必要做这个,因为有了IOC也会增加项目的复杂度。
二:在项目中实现IOC
1.创建一个beans.properties文件,用于存放bean的具体实现:
2.创建一个制造bean的工厂,通过反射来创造写在配置文件里面的那些bean
3.创建一个InitBeanFactoryServlet,该servlet在web.xml里面不需要配置对应的map,因为只有在初始化的时候会用到,但是需要设置启动项为0,让他最先初始化。
该类的作用:在容器启动的时候调用PropertiesBeanFactory来产生写在properties配置文件里面的类,把他们放在ServletContext里面。
4.创建一个BaseServelt,所有别的servlet都继承自他,他的子类会先调用他的service方法,通过反射查看子类里面有没有bean的set方法,如果有就在ServletContext里面获取对应的bean。(第三部的时候,InitBeanFactoryServlet 已经将所有的bean都放到了ServletContext里面)
有的项目在管理DAO的时候会抽象出一个interface,如ArticleDao;然后去做一些他的实现:如ArticleDaoForDb2或者ArticleDaoForOracle。这样在Servlet里面new一个ArticleDao可以写成:
ArticleDao articleDao=new ArticleDaoForOracle
这种做法带来的问题:项目一大,就有很多dao类,如ContentDao,PersonDao等等等。如果有一天要将他们的实现从ForOracle改成ForDb2,这样在代码里面的改动就会很大。
IOC:控制翻转,本来需要在代码里面将某个类的具体实现new出来的,现在不用new了,只需要在配置文件做一下配置。这样一来,如果我们想将dao的实现从ForOracle改成ForDb2。只需要在一个配置文件里面改就行了,不用再在很多个的servlet类里面一个个的改。
个人认为IOC适用于一些大项目,对于一些小项目,本身就只有一个实现,就没有必要做这个,因为有了IOC也会增加项目的复杂度。
二:在项目中实现IOC
1.创建一个beans.properties文件,用于存放bean的具体实现:
articleDao=bruce.zhao.cms.backend.dao.impl.ArticleDaoImpl channelDao=bruce.zhao.cms.backend.dao.impl.ChannelDaoImpl
2.创建一个制造bean的工厂,通过反射来创造写在配置文件里面的那些bean
public class PropertiesBeanFactory implements BeanFactory{ //该工厂类产生的bean都放在这个map里面 Map beans=new HashMap(); //默认的properties文件的名字为:beans.properties private String congfigLocation="beans.properties"; public PropertiesBeanFactory(){ init(); } public PropertiesBeanFactory(String configLocation){ setCongfigLocation(configLocation); init(); } private void init(){ try { Properties properties=new Properties(); //将properties文件load进来 properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream(congfigLocation)); //将properties对象转换为一个set,便于遍历 Set set=properties.entrySet(); //循环遍历properties文件里面的一条条记录 for (Iterator iterator=set.iterator(); iterator.hasNext(); ) { Map.Entry entry=(Map.Entry)iterator.next(); String keyString=(String)entry.getKey(); String className=(String)entry.getValue(); Class clz=Class.forName(className); Object bean= clz.newInstance(); //将实例化好的类放进map beans.put(keyString, bean); } } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } public Object getBean(String name){ return beans.get(name); } /** * @return the congfigLocation */ public String getCongfigLocation() { return congfigLocation; } /** * @param congfigLocation the congfigLocation to set */ public void setCongfigLocation(String congfigLocation) { this.congfigLocation = congfigLocation; } }
3.创建一个InitBeanFactoryServlet,该servlet在web.xml里面不需要配置对应的map,因为只有在初始化的时候会用到,但是需要设置启动项为0,让他最先初始化。
<servlet> <description></description> <display-name>InitBeanFactoryServlet</display-name> <servlet-name>InitBeanFactoryServlet</servlet-name> <servlet-class>bruce.zhao.cms.backend.view.InitBeanFactoryServlet</servlet-class> <init-param> <param-name>configLocation</param-name> <param-value>beans.properties</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet>
该类的作用:在容器启动的时候调用PropertiesBeanFactory来产生写在properties配置文件里面的类,把他们放在ServletContext里面。
public class InitBeanFactoryServlet extends HttpServlet { private static final long serialVersionUID = 1L; public static final String INIT_FACTORY_NAME="_my_bean_factory"; /* (non-Javadoc) * @see javax.servlet.GenericServlet#init() */ @Override public void init(ServletConfig config) throws ServletException { BeanFactory beanFactory=null; String configLocation =config.getInitParameter("configLocation"); if (configLocation==null) { //如果在web.xml里面没有配置properties文件的名字则 beanFactory=new PropertiesBeanFactory(); }else { beanFactory=new PropertiesBeanFactory(configLocation); } config.getServletContext().setAttribute(INIT_FACTORY_NAME, beanFactory); } }
4.创建一个BaseServelt,所有别的servlet都继承自他,他的子类会先调用他的service方法,通过反射查看子类里面有没有bean的set方法,如果有就在ServletContext里面获取对应的bean。(第三部的时候,InitBeanFactoryServlet 已经将所有的bean都放到了ServletContext里面)
public class BaseServelt extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response) */ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { BeanFactory beanFactory=(BeanFactory) getServletContext().getAttribute(InitBeanFactoryServlet.INIT_FACTORY_NAME); Method[] methods=this.getClass().getMethods(); for (Method method : methods) { if (method.getName().startsWith("set")) { String propertyName=method.getName().substring(3); StringBuffer sb =new StringBuffer(propertyName); sb.replace(0, 1, (propertyName.charAt(0)+"").toLowerCase()); propertyName=sb.toString(); Object bean= beanFactory.getBean(propertyName); try { method.invoke(this, bean); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } super.service(request, response); } }
相关文章推荐
- Android注解使用之通过annotationProcessor注解生成代码实现自己的ButterKnife框架
- SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论 SignalR 简单示例 通过三个DEMO学会SignalR的三种实现方式 SignalR推送框架两个项目永久连接通讯使用 SignalR 集线器简单实例2 用SignalR创建实时永久长连接异步网络应用程序
- Android注解使用之通过annotationProcessor注解生成代码实现自己的ButterKnife框架
- 简单完整的代码,通过这个代码你将对RSA加密算法在Java中的实现方法有一个初步的了解,这个类,你可以直接使用,水平高的,就自己修改完善下代码。
- 使用三方框架FlashView在自己的项目中实现图片轮播
- 【转载】使用Json比用string返回数据更友好,也更面向对象一些 |Asp.net MVC 2.0 + Unity 2.0(IoC) + EF4.0 实例:RoRoWoBlog 开源项目框架代码
- java web项目使用CORS方法实现跨域请求方案
- 在使用JS框架之前自己写的一些工具代码
- J2EE项目系列(四)--SSM框架构建积分系统和基本商品检索系统(Spring+SpringMVC+MyBatis)(3)Ajax使用详解(级联列表)以及企业级报表Excel导入导出实现
- 框架 day76 涛涛商城项目-使用json模板实现带分类的产品规格信息存储及展示
- Python使用Scrapy爬虫框架全站爬取图片并保存本地的实现代码
- Unity IOC容器通过配置实现类型映射的几种基本使用方法
- 【完整靠谱版】结合公司项目,仔细总结自己使用百度编辑器实现FTP上传的完整过程
- spring 框架中的依赖注入(IOC--设值注入)---使用xml简单配置文件---的具体实例的简单实现
- 在使用JS框架之前自己写的一些工具代码
- iOS:使用Github托管自己本地的项目代码方式二(客户端方式: Github Desktop)
- SharpPcap网络包捕获框架的使用--实例代码在vs2005调试通过
- Java之——使用proguard混淆java web项目代码
- Delphi使用android的NDK是通过JNI接口,封装好了,不用自己写本地代码,直接调用
- Spring security 在项目中的使用第二篇之代码实现阶段