最近想学一下新东西,看到spring3,struts2,ibatis3都出来了,以前也不怎么了解,今天在网上看了点东西,发给“自己”以后学习吧。
先了解下 spring 注入:
Spring有3种注入,接口注入,构造子注入,设值注入
Type1 接口注入
我们常常借助接口来将调用者与实现者分离。如:
public class ClassA {
private InterfaceB clzB;
public init() {
Ojbect obj =
Class.forName(Config.BImplementation).newInstance();
clzB = (InterfaceB)obj;
}
……
}
上面的代码中,ClassA依赖于InterfaceB的实现,如何获得InterfaceB实现类的实例?传统的方法是在代码中创建InterfaceB实现类的实例,并将起赋予clzB。而这样一来,ClassA在编译期即依赖于InterfaceB的实现。为了将调用者与实现者在编译期分离,于是有了上面的代码,我们根据预先在配置文件中设定的实现类的类名,动态加载实现类,并通过InterfaceB强制转型后为ClassA所用。
这就是接口注入的一个最原始的雏形。
而对于一个Type1型IOC容器而言,加载接口实现并创建其实例的工作由容器完成,如J2EE开发中常用的Context.lookup(ServletContext.getXXX),都是Type1型IOC的表现形式。Apache Avalon是一个典型的Type1型IOC容器。
Type2 构造子注入
构造子注入,即通过构造函数完成依赖关系的设定,如:
public class DIByConstructor
{
private final DataSource dataSource;
private final String message;
public DIByConstructor(DataSource ds, String msg)
{
this.dataSource = ds;
this.message = msg;
}
……
}
可以看到,在Type2类型的依赖注入机制中,依赖关系是通过类构造函数建立,容器通过调用类的构造方法,将其所需的依赖关系注入其中。PicoContainer(另一种实现了依赖注入模式的轻量级容器)首先实现了Type2类型的依赖注入模式。
Type3 设值注入
在各种类型的依赖注入模式中,设值注入模式在实际开发中得到了最广泛的应用(其中很大一部分得力于Spring框架的影响)。
在笔者看来,基于设置模式的依赖注入机制更加直观、也更加自然。Quick Start中的示例,就是典型的设置注入,即通过类的setter方法完成依赖关系的设置。
几种依赖注入模式的对比总结
接口注入模式因为具备侵入性,它要求组件必须与特定的接口相关联,因此并不被看好,实际使用有限。Type2和Type3的依赖注入实现模式均具备无侵入性的特点。
Type3 设值注入的优势
1、对于习惯了传统JavaBean开发的程序员而言,通过setter方法设定依赖关系显得更加直观,更加自然。
2、如果依赖关系(或继承关系)较为复杂,那么Type2模式的构造函数也会相当庞大(我们需要在构造函数中设定所有依赖关系),此时Type3模式往往更为简洁。
我的理解:依赖关系(或继承关系)较为复杂,指的是,属性较多,需要写很多的set和get方法。
3、对于某些第三方类库而言,可能要求我们的组件必须提供一个默认的构造函数(如Struts中的Action),此时Type2类型的依赖注入机制就体现出其局限性,难以完成我们期望的功能。
可见,Type2和Type3模式各有千秋,而Spring、PicoContainer都对Type2和Type3类型的依赖注入机制提供了良好支持。这也就为我们提供了更多的选择余地。理论上,以Type2类型为主,辅之以Type3类型机制作为补充,可以达到最好的依赖注入效果,不过对于基于Spring Framework开发的应用而言,Type3使用更加广泛。
给个简单的例子:
spring 配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" default-autowire="byName" default-lazy-init="false"> <!-- component-scan自动搜索@Component , @Controller , @Service , @Repository等标注的类 --> <!-- 默认值如果适合,该项可以不用修改 --> <context:component-scan base-package="com.**.service.impl" /> </beans>
服务实现类:
package com.mylink.mipbs.service.impl; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.util.*; import javacommon.base.*; import javacommon.util.*; import cn.org.rapid_framework.util.*; import cn.org.rapid_framework.web.util.*; import cn.org.rapid_framework.page.*; import cn.org.rapid_framework.page.impl.*; import com.mylink.mipbs.model.*; import com.mylink.mipbs.dao.*; import com.mylink.mipbs.service.impl.*; import com.mylink.mipbs.service.*; //加上注解,供其它地方调用。
@Component("permissionManager") @Transactional public class PermissionManagerImpl extends BaseManager<Permission,java.lang.Integer> implements PermissionManager { private PermissionDao permissionDao; /**增加setXXXX()方法,spring就可以通过autowire自动设置对象属性*/ public void setPermissionDao(PermissionDao dao) { this.permissionDao = dao; } public EntityDao getEntityDao() { return this.permissionDao; } @Transactional(readOnly=true) public Page findByPageRequest(PageRequest pr) { return permissionDao.findByPageRequest(pr); } }
事件类调用:
package com.mylink.mipbs.action; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javacommon.util.extjs.ExtJsPageHelper; import javacommon.util.extjs.ListRange; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.lang.StringUtils; import cn.org.rapid_framework.page.Page; import cn.org.rapid_framework.page.PageRequest; import com.mylink.mipbs.model.Permission; import com.opensymphony.xwork2.Preparable; import com.opensymphony.xwork2.ModelDriven; import static javacommon.util.extjs.Struts2JsonHelper.*; import java.util.*; import javacommon.base.*; import javacommon.util.*; import cn.org.rapid_framework.util.*; import cn.org.rapid_framework.web.util.*; import cn.org.rapid_framework.page.*; import cn.org.rapid_framework.page.impl.*; import com.mylink.mipbs.model.*; import com.mylink.mipbs.dao.*; import com.mylink.mipbs.service.impl.*; import com.mylink.mipbs.service.*; public class PermissionAction extends BaseStruts2Action implements Preparable,ModelDriven{ //默认多列排序,example: username desc,createTime asc protected static final String DEFAULT_SORT_COLUMNS = null; //forward paths protected static final String QUERY_JSP = "/pages/Permission/query.jsp"; protected static final String LIST_JSP= "/pages/Permission/list.jsp"; protected static final String CREATE_JSP = "/pages/Permission/create.jsp"; protected static final String EDIT_JSP = "/pages/Permission/edit.jsp"; protected static final String SHOW_JSP = "/pages/Permission/show.jsp"; //redirect paths,startWith: ! protected static final String LIST_ACTION = "!/pages/Permission/list.do"; private PermissionManager permissionManager; private Permission permission; java.lang.Integer id = null; private String[] items; public void prepare() throws Exception { if (isNullOrEmptyString(id)) { permission = new Permission(); } else { permission = (Permission)permissionManager.getById(id); } } /** 通过spring自动注入 */ public void setPermissionManager(PermissionManager manager) { this.permissionManager = manager; } public Object getModel() { return permission; } public void setId(java.lang.Integer val) { this.id = val; } public void setItems(String[] items) { this.items = items; } /** * ExtGrid使用 * 列表 * @throws IOException */ public void extlist() throws IOException { PageRequest<Map> pr = ExtJsPageHelper.createPageRequestForExtJs(getRequest(), DEFAULT_SORT_COLUMNS); Page page = permissionManager.findByPageRequest(pr); List<Permission> Permissionlist = (List) page.getResult(); ListRange<Permission> resultList = new ListRange<Permission>(); resultList.setList(Permissionlist); resultList.setTotalSize(page.getTotalCount()); resultList.setMessage("ok"); resultList.setSuccess(true); outJson(resultList); } /** * extGrid保存 * @throws IOException */ public void extsave() throws IOException { Map<String, Object> result = new HashMap<String, Object>(); try { permissionManager.save(permission); result.put("success", true); result.put("msg", "添 加 成 功!"); } catch (Exception e) { result.put("failure", true); result.put("msg", e.getMessage()); e.printStackTrace(); } outJson(result); } /** * extGrid修改 * @throws IOException */ public void extupdate() throws IOException { Map<String, Object> result = new HashMap<String, Object>(); try { permissionManager.update(permission); result.put("success", true); result.put("msg", "修 改 成 功!"); } catch (Exception e) { result.put("failure", true); result.put("msg", e.getMessage()); e.printStackTrace(); } outJson(result); } /** * extGrid删除 * @throws IOException */ public void extdelete() throws IOException { String ids = getRequest().getParameter("ids"); String[] idarray = ids.split(","); Map<String, Object> result = new HashMap<String, Object>(); try { for (int i = 0; i < idarray.length; i++) { java.lang.Integer id = new java.lang.Integer((String)idarray[i]); permissionManager.removeById(id); } result.put("success", true); result.put("msg", "删除成功"); } catch (Exception e) { result.put("failure", true); result.put("msg", e.getMessage()); e.printStackTrace(); } outJson(result); } }