- 浏览: 23502 次
- 性别:
- 来自: 杭州
最新评论
-
phantom:
<pre name="code" c ...
Guice项目实战(一) -
samuelyuan:
没人关注,顶一下!
Guice项目实战(一) -
ecsoftcn:
ActionSupport
<pre name=&qu ...
Guice项目实战(一) -
ecsoftcn:
ActionProxy
<pre name=" ...
Guice项目实战(一) -
ecsoftcn:
ActionEnhancer
<pre name=&q ...
Guice项目实战(一)
引言
公元二零零七年,开源领域各IoC框架战火不断。Spring大红大紫,独领风骚;PicoContainer、Hivemind紧随其后,穷追不舍。正当各路豪杰稳步发展之时,一匹黑马悄悄杀进江湖,这就是号称比Spring快100倍的Guice,从此江湖又起风云!
Guice是由Bob lee设计的基于Java5 Annotation的轻量级IoC容器,它把组织对象依赖关系的逻辑从XML文件转移到对象内部,巧妙的实现了DI模式。本文并不打算详细讲解Guice的语法,如果你尚且不知道Guice是什么,可以先阅读附录中提供的文章了解Guice相关信息。本文余下部分将用一个以Guice为基础的简单的MVC模式的参考实现(实在是不知道应该叫什么,暂且就称之为参考实现吧)以及在该实现基础上开发的XXX示例来深入Guice应用开发实战。
完整内容请参阅附件中的文档,以及AromaRI的实现代码。文档正在完善中···
附件AromaRI项目源码是一个完整的Eclipse工程,运行ant脚本可以编译、测试和打包web应用。
- Guice.rar (95.2 KB)
- 描述: document
- 下载次数: 710
- AromaRI.rar (2.6 MB)
- 描述: AromaRI项目代码
- 下载次数: 1523
- Guice.rar (95.2 KB)
- 描述: Guice项目实战
- 下载次数: 682
评论
9 楼
phantom
2007-06-15
http://ecsoftcn.iteye.com/
8 楼
samuelyuan
2007-05-16
没人关注,顶一下!
7 楼
ecsoftcn
2007-05-11
ActionSupport
/* * EsayJF.com Inc. * * Copyright (c) 2006-2008 All Rights Reserved. */ package com.aroma.core; import java.lang.reflect.Method; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.aroma.core.util.AromaUtil; /** * An implementation of {@link Action}. * * <p> * Extends from this class , you can difine more than one method in a single Action. * * @author ecsoftcn@hotmail.com * * @version $Id: ActionSupport.java, 2007-4-28 上午12:48:13 Tony Exp $ */ public abstract class ActionSupport implements Action { /** Logging */ private static final Log logger = LogFactory.getLog(ActionSupport.class); private static final Class[] COMMAND_METHOD_PARAM = new Class[] { ActionContext.class }; private String command; /* * @see com.aroma.core.Action#execute(com.aroma.core.ActionContext) */ public final void execute(ActionContext context) { String command = getCommand(); String methodName = getMethodName(command); Method method = null; try { method = getClass().getDeclaredMethod(methodName, COMMAND_METHOD_PARAM); } catch (NoSuchMethodException e) { logger.error("[execute] no method named '" + methodName + "' in " + getClass().getSimpleName(), e); throw new RuntimeException("Can't find '" + methodName + "' method!", e); } try { if (logger.isDebugEnabled()) { logger.debug("[execute] method '" + methodName + "' in " + getClass().getSimpleName() + " have been invoked!"); } method.invoke(this, new Object[] { context }); } catch (Exception e) { logger.error("[execute] error occured while invoke '" + methodName + "' in" + getClass().getSimpleName(), e); throw new RuntimeException("Fail to execute '" + methodName + "' method!", e); } } /** * By default,user may override this method directly. * * <p> * If you want to add more than one method in a action , just do it follow this pattern: * * <b>public void doXxxXxxx(ActionCotext context){}</b> * * @param context */ public void doExecute(ActionContext context) { } /** * Obtain the real method by user command and default command prefix. * * @param command * * @return current request method */ private String getMethodName(String command) { String first = command.substring(0, 1); return Globals.COMMAND_METHOD_PREFIX + first.toUpperCase() + command.substring(1); } /** * @return the command */ public final String getCommand() { if (!AromaUtil.isEmptyOrNull(command)) { return command; } return "execute"; } /** * @param command the command to set */ public final void setCommand(String command) { this.command = command; } }
6 楼
ecsoftcn
2007-05-11
ActionProxy
/* * EsayJF.com Inc. * * Copyright (c) 2006-2008 All Rights Reserved. */ package com.aroma.core; import java.lang.reflect.Method; import java.util.Iterator; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.aroma.core.util.AromaUtil; /** * * @author ecsoftcn@hotmail.com * * @version $Id: ActionProxy.java, 2007-5-1 下午04:39:48 Tony Exp $ */ public class ActionProxy implements Action { /** Logging */ private static final Log logger = LogFactory.getLog(ActionProxy.class); private static final Class[] COMMAND_METHOD_PARAM = new Class[] { Map.class }; private String command; private Object proxy; public ActionProxy(Object proxy) { this(proxy, null); } public ActionProxy(Object proxy, String command) { this.command = command; this.proxy = proxy; } /* * @see com.aroma.core.Action#execute(com.aroma.core.ActionContext) */ public void execute(ActionContext context) { if (AromaUtil.isEmptyOrNull(proxy)) { throw new RuntimeException("[ActionProxy] proxy object can't be null!"); } String command = getCommand(); String methodName = getMethodName(command); Method method = null; try { method = proxy.getClass().getDeclaredMethod(methodName, COMMAND_METHOD_PARAM); } catch (NoSuchMethodException e) { logger.error("[execute] no method named '" + methodName + "' in " + proxy.getClass().getSimpleName(), e); throw new RuntimeException("Can't find '" + methodName + "' method!", e); } try { if (logger.isDebugEnabled()) { logger.debug("[execute] method '" + methodName + "' in " + proxy.getClass().getSimpleName() + " have been invoked!"); } Object results = method.invoke(proxy, new Object[] { context.getParameters() }); if (!AromaUtil.isEmptyOrNull(results)) { if (results instanceof Map) { Map resultMap = (Map) results; for (Iterator iter = resultMap.keySet().iterator(); iter.hasNext();) { Object key = iter.next(); Object value = resultMap.get(key); if (key instanceof String) { String keyStr = (String) key; if (Globals.NEXT_PAGE.equals(keyStr) && value instanceof String) { context.setNextPage((String) value); }else{ context.addResult(keyStr, value); } } } } } } catch (Exception e) { logger.error("[execute] error occured while invoke '" + methodName + "' in" + proxy.getClass().getSimpleName(), e); throw new RuntimeException("Fail to execute '" + methodName + "' method!", e); } } /** * Obtain the real method by user command and default command prefix. * * @param command * * @return current request method */ private String getMethodName(String command) { String first = command.substring(0, 1); return Globals.COMMAND_METHOD_PREFIX + first.toUpperCase() + command.substring(1); } /** * @return the command */ public String getCommand() { if (!AromaUtil.isEmptyOrNull(command)) { return command; } return "execute"; } }
5 楼
ecsoftcn
2007-05-11
ActionEnhancer
/* * EsayJF.com Inc. * * Copyright (c) 2006-2008 All Rights Reserved. */ package com.aroma.core; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.Map; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.aroma.core.util.AromaUtil; /** * * @author ecsoftcn@hotmail.com * * @version $Id: ActionEnhancer.java, 2007-4-28 下午07:16:44 Tony Exp $ */ public class ActionEnhancer { /** Logging */ private static final Log logger = LogFactory.getLog(ActionEnhancer.class); private ActionEnhancer() { } /** * * @param object * @param data * @return */ public static Object enhance(Object object, Map data) { if (AromaUtil.isEmptyOrNull(object) || AromaUtil.isEmptyOrNull(data)) { if (logger.isDebugEnabled()) { logger.debug("Action or ActionContext may be null , so ignore it!"); } return object; } autowireActionProperties(object, data); return object; } private static void autowireActionProperties(Object object, Map data) { Class superClass = object.getClass(); Class currentClass; while (true) { currentClass = superClass; Field[] fields = currentClass.getDeclaredFields(); if (logger.isDebugEnabled()) { logger.debug("Start to inject [" + currentClass.getSimpleName() + "]'s instance variable! "); } for (Field field : fields) { String name = field.getName(); Object value = data.get(name); try { Autowire autowire = field.getAnnotation(Autowire.class); if (AromaUtil.isEmptyOrNull(autowire)) { if (logger.isDebugEnabled()) { logger.debug("[" + currentClass.getSimpleName() + "] variable '" + name + "' didn't have [Autowire] annotation , so inject it by it's setter method!"); } if (PropertyUtils.isWriteable(object, name)) { BeanUtils.setProperty(object, name, value); if (logger.isDebugEnabled()) { logger.debug("[" + currentClass.getSimpleName() + "] set variable '" + name + "' by value '" + value + "'"); } } } else { if (logger.isDebugEnabled()) { logger.debug("[" + currentClass.getSimpleName() + "] variable '" + name + "' has a [Autowire] annotation , so inject it directly!"); } if (!AromaUtil.isEmptyOrNull(value)) { field.setAccessible(true); field.set(object, value); if (logger.isDebugEnabled()) { logger.debug("[" + currentClass.getSimpleName() + "] set variable '" + name + "' by value '" + value + "'"); } } } } catch (IllegalArgumentException e) { if (logger.isWarnEnabled()) { logger.warn("[" + currentClass.getSimpleName() + "] exception occured while inject variable '" + name + "'", e); } } catch (IllegalAccessException e) { if (logger.isWarnEnabled()) { logger.warn("[" + currentClass.getSimpleName() + "] exception occured while inject variable '" + name + "'", e); } } catch (InvocationTargetException e) { if (logger.isWarnEnabled()) { logger.warn("[" + currentClass.getSimpleName() + "] exception occured while inject variable '" + name + "'", e); } } } superClass = currentClass.getSuperclass(); if (superClass == null || superClass == Object.class) { break; } } } }
4 楼
ecsoftcn
2007-05-11
AromaServlet
/* * EsayJF.com Inc. * * Copyright (c) 2006-2008 All Rights Reserved. */ package com.aroma.core; import java.io.IOException; import java.util.Iterator; import java.util.Map; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.aroma.core.container.Container; import com.aroma.core.container.support.SingletonContainerLoader; import com.aroma.core.util.AromaUtil; /** * @author ecsoftcn@hotmail.com * * @version $Id: AromaServlet.java,v 1.0 Apr 19, 2007 10:56:18 AM Tony Exp $ */ public class AromaServlet extends HttpServlet { /** Logging */ private static final Log logger = LogFactory.getLog(AromaServlet.class); private static final long serialVersionUID = 5858340596717871501L; private Container container; /* * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig) */ @Override public void init(ServletConfig context) throws ServletException { super.init(context); if (container == null) { container = (Container) context.getServletContext().getAttribute(Globals.AROMA_RI_CONTAINER); if (container == null) { String modules = context.getInitParameter(Globals.AROMA_CUSTOM_MODULES); String stage = context.getInitParameter(Globals.AROMA_STAGE); String configFile = context.getInitParameter(Globals.AROMA_CUSTOM_CONFIG_FILE); String[] moduleArray = null; if (!AromaUtil.isEmptyOrNull(modules)) { moduleArray = modules.split(","); } if (AromaUtil.isEmptyOrNull(configFile)) { configFile = Globals.AROMA_DEFALUT_CONFIG_FILE; } try { container = SingletonContainerLoader.create(context.getServletContext().getResourceAsStream(configFile), stage, moduleArray); } catch (Exception e) { throw new ServletException(e); } context.getServletContext().setAttribute(Globals.AROMA_RI_CONTAINER, container); } } } /* * @see javax.servlet.GenericServlet#destroy() */ @Override public void destroy() { super.destroy(); if (container != null) { container.destroy(); container = null; } } /* * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { ActionContext context = new DefaultActionContext(); try { if (!getRequestPath(req, res).endsWith(Globals.EXTENTAION_DO)) { req.getRequestDispatcher(getRequestPath(req, res)).forward(req, res); } else { beforeProcess(req, res, context); Action action = null; Object target = ActionEnhancer.enhance(container.getBean(getActionName(req, res)), context.getParameters()); if (target instanceof Action) { action = (Action) target; } else { action = new ActionProxy(target, (String) context.getParameter(Globals.DEFAULT_COMMAND_NAME)); } if (AromaUtil.isEmptyOrNull(action)) { handleError(req, res, "The action that you just request dose not exist!"); } action.execute(context); afterProcess(req, res, context); req.getRequestDispatcher(getResultPage(req, res, context)).forward(req, res); } } catch (Throwable e) { handleException(req, res, "Error occured while processing request !", e); } } ··· }
3 楼
ecsoftcn
2007-05-11
SingletonContainerLoader
/* * EsayJF.com Inc. * * Copyright (c) 2006-2008 All Rights Reserved. */ package com.aroma.core.container.support; import java.io.InputStream; import com.aroma.core.config.ConfigParser; import com.aroma.core.config.support.DefaultConfigParser; import com.aroma.core.container.Container; /** * Singleton and Thread-safe Container Loader. * * @author ecsoftcn@hotmail.com * * @version $Id: ContainerFactory.java, 2007-4-26 下午10:05:28 Tony Exp $ */ public class SingletonContainerLoader { static final ThreadLocal<Container> localContext = new ThreadLocal<Container>(); private static boolean initialized = false; private SingletonContainerLoader() { } /** * Create a {@link Container} instance and put it in {@link ThreadLocal<Container>} * * @param in config file's inputstream * * @return Container * * @throws Exception */ public static Container create(InputStream in) throws Exception { return create(in, null); } /** * Create a {@link Container} instance and put it in {@link ThreadLocal<Container>} * * @param in config file's inputstream * * @param stage Guice's running stage * * @return Container * * @throws Exception */ public static Container create(InputStream in, String stage) throws Exception { return create(in, stage, null); } /** * Create a {@link Container} instance and put it in {@link ThreadLocal<Container>} * * @param in config file's inputstream * * @param stage Guice's running stage * * @param modules custom modules * * @return Container * * @throws Exception */ public static Container create(InputStream in, String stage, String[] moduleArray) throws Exception { if (!initialized) { ConfigParser configParser = new DefaultConfigParser(); Container container = new DefaultContainer(configParser.parse(in), stage, moduleArray); container.init(); if (container == null) { throw new Exception("AromaRI Container setup failure!"); } localContext.set(container); initialized = true; } return getCurrentThreadContainer(); } /** * Get current thread's container. * * <p> * {@link Action} and any other classes can obtain current thread's {@link Container} instance through this method. * * <b>Example:</b> Container container = SingletonContainerLoader.getCurrentThreadContainer(); * * @return */ public static Container getCurrentThreadContainer() { return localContext.get(); } }
2 楼
ecsoftcn
2007-05-11
几个重要类的细节(一)
DefaultContainer
DefaultContainer
/* * EsayJF.com Inc. * * Copyright (c) 2006-2008 All Rights Reserved. */ package com.aroma.core.container.support; import static com.google.inject.Scopes.SINGLETON; import static com.google.inject.name.Names.named; import static com.google.inject.servlet.AromaServletModule.APPLICATION; import static com.google.inject.servlet.ServletScopes.REQUEST; import static com.google.inject.servlet.ServletScopes.SESSION; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.aroma.core.Globals; import com.aroma.core.config.Component; import com.aroma.core.container.Container; import com.aroma.core.util.AromaUtil; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.Scope; import com.google.inject.Stage; import com.google.inject.servlet.AromaServletModule; /* * An Container as a wrapper of Guice's {@link Injector}. * * <p> * <b>some examples:</b> <code> * AdminAction adminAction = container.getBean(AdminAction.class); * * UserAction userAction = (UserAction)container.getBean("user"); * * LoginService adminLogin = container.getBean(LoginService.class,new MyAnnotation()); * </code> * * @author ecsoftcn@hotmail.com * * @version $Id: DefaultContainer.java,v 1.0 Apr 18, 2007 1:48:30 PM Tony Exp $ */ public class DefaultContainer implements Container { /* Logging */ private static final Log logger = LogFactory.getLog(DefaultContainer.class); /* Goole Guice's Container */ private Injector injector; /* Action container's array */ private Component[] components = new Component[] {}; /* Module's list */ private List<AbstractModule> modules = new ArrayList<AbstractModule>(); /* Current support scopes */ private static final Map<String, Scope> scopes = new HashMap<String, Scope>(); /* Guice's running stages */ private static final Map<String, Stage> stages = new HashMap<String, Stage>(); /* Initializing flag */ private boolean initialized = false; private Stage stage = Stage.PRODUCTION; static { scopes.put(Globals.SCOPES_REQUEST, REQUEST); scopes.put(Globals.SCOPES_SESSION, SESSION); scopes.put(Globals.SCOPES_APPLICATION, APPLICATION); scopes.put(Globals.SCOPES_SINGLETON, SINGLETON); stages.put(Stage.PRODUCTION.name(), Stage.PRODUCTION); stages.put(Stage.DEVELOPMENT.name(), Stage.DEVELOPMENT); } public DefaultContainer(Component[] components) { this(components, null); } public DefaultContainer(Component[] components, String stage) { this(components, stage, null); } public DefaultContainer(Component[] components, String stage, String[] moduleArray) { if (!AromaUtil.isEmptyOrNull(components)) { this.components = components; } if (!AromaUtil.isEmptyOrNull(stage) && !AromaUtil.isEmptyOrNull(scopes.get(stage))) { this.stage = stages.get(stage); } if (moduleArray != null && moduleArray.length > 0) { for (String name : moduleArray) { try { Class module = AromaUtil.loadClass(name); this.modules.add((AbstractModule) module.newInstance()); } catch (Exception e) { logger.error("Error occured while regist module [" + name + "]", e); } } } } /* * * @see com.aroma.core.container.Container#init() */ public void init() { if (!initialized) { if (logger.isInfoEnabled()) { logger.info("***************************************************************"); logger.info("* *"); logger.info("* AromaRI Container *"); logger.info("* *"); logger.info("***************************************************************"); } long start = System.currentTimeMillis(); injector = Guice.createInjector(stage, new AbstractModule() { /* * @see com.google.inject.AbstractModule#configure() */ @Override @SuppressWarnings("unchecked") protected void configure() { if (logger.isInfoEnabled()) { logger.info("Install ServletModule [" + AromaServletModule.class.getName() + "]"); } install(new AromaServletModule()); for (AbstractModule module : modules) { if (logger.isInfoEnabled()) { logger.info("Install CustomModule [" + module.getClass().getName() + "]"); } install(module); } for (Component component : components) { if (!AromaUtil.isEmptyOrNull(component.getScope())) { Scope scope = scopes.get(component.getScope()); if (!AromaUtil.isEmptyOrNull(scope)) { if (logger.isInfoEnabled()) { logger .info("Binding Component [" + component.getAction().getName() + "] in Scope [" + component.getScope() + "]"); } bind(component.getAction()).annotatedWith(named(component.getName())).to(component.getAction()).in(scope); continue; } } if (logger.isInfoEnabled()) { logger.info("Binding Component [" + component.getAction().getName() + "]"); } bind(component.getAction()).annotatedWith(named(component.getName())).to(component.getAction()); } } }); initialized = true; long time = System.currentTimeMillis() - start; if (logger.isInfoEnabled()) { logger.info("Container finish initialized! Cost " + time + "ms."); } } } /* * * @see com.aroma.core.container.Container#destroy() */ public void destroy() { if (injector != null) { injector = null; } } /* * Obtain an object from container by a special name. * * <p> * <b>Warning</b> * You can call this method only when get a {@link Action} instance from Container, * * because only {@link Action} instance have name attribute in container. * * @param name bean's name * * @return Object */ @SuppressWarnings("unchecked") public Object getBean(String name) { for (Component component : components) { if (component.getName().equals(name)) { return getBean(component.getAction(), named(name)); } } return null; } /* * Obtain an instance of Class<T> . * * @param <T> generic type * * @param type instance type * * @return T */ public <T> T getBean(Class<T> type) { T instance = null; try { instance = injector.getInstance(type); if (logger.isDebugEnabled()) { logger.debug("Get an instance from container [" + instance.getClass().getName() + "]"); } } catch (Throwable e) { if (logger.isWarnEnabled()) { logger.warn("An exception has occured while obtain an instance of " + type.getSimpleName(), e); } } return instance; } /* * Obtain an instance of Class<T> . * * @param <T> generic type * * @param type instance type * * @param annotation annotation instance * * @return T */ public <T> T getBean(Class<T> type, Annotation annotation) { T instance = null; try { instance = injector.getInstance(Key.get(type, annotation)); if (logger.isDebugEnabled()) { logger.debug("Get an instance from container [" + instance.getClass().getName() + "]"); } } catch (Throwable e) { if (logger.isWarnEnabled()) { logger.warn("An exception has occured while obtain an instance of " + type.getSimpleName(), e); } } return instance; } }
1 楼
ecsoftcn
2007-05-11
<p><font size='3'>附件一和附件三的内容是一样的,因为我在上传的时候重复了,但是不能删除</font><img src='/javascripts/fckeditor/editor/images/smiley/msn/sad_smile.gif' alt=''/></p>
<p> </p>
<p><font size='3'>下面把AromaRI的工作原理结构图发上来:</font></p>
<p><img src='http://ecsoftcn.iteye.com/upload/picture/pic/3301/88c8175a-c3d2-42a6-bc78-19ab6d7bdcfc.png ' alt='AromaRI工作原理结构图'/></p>
<p> </p>
<p><font size='3'>AromaRI只是一个简单的MVC层,由Guice充当IoC容器的角色。</font></p>
<p><font size='3'/></p>
<p><font size='3' color='#ff0000'><strong><em>目前文档只完成了一小部分,其他章节会陆续发布。</em></strong></font></p>
<p> </p>
<p><font size='3'>下面把AromaRI的工作原理结构图发上来:</font></p>
<p><img src='http://ecsoftcn.iteye.com/upload/picture/pic/3301/88c8175a-c3d2-42a6-bc78-19ab6d7bdcfc.png ' alt='AromaRI工作原理结构图'/></p>
<p> </p>
<p><font size='3'>AromaRI只是一个简单的MVC层,由Guice充当IoC容器的角色。</font></p>
<p><font size='3'/></p>
<p><font size='3' color='#ff0000'><strong><em>目前文档只完成了一小部分,其他章节会陆续发布。</em></strong></font></p>
相关推荐
《Guice开发实战》 Guice,全称为Google Guice,是Google开发的一款轻量级的依赖注入(Dependency Injection,DI)框架,主要用于简化Java应用的构造和管理。依赖注入是一种设计模式,它有助于降低代码之间的耦合度...
《Java Web典型模块与项目实战大全(程序员典藏)》以实战开发为原则,以Java EE主流框架整合应用及项目开发为主线,通过Java Web开发中最常见的19个典型模块和5个完整的项目案例,详细介绍了Struts 2.x、Spring、...
5. **实战案例**: 提供实际的代码示例,演示如何在项目中应用 Guice。 通过阅读文档和运行示例,开发者可以快速理解和掌握 Guice 的使用方法,将其有效地应用于实际项目中,提升代码质量。 **总结** Guice 是一个...
Guice是Google开发的一款轻量级的Inversion of Control(IoC)容器,它通过依赖注入(Dependency Injection,DI)来管理对象的生命周期和装配。Guice-3.0是Guice的一个版本,包含了核心库guice-3.0.jar,以及与...
10. **实战示例**:博客中可能包含了一些实际的代码示例,展示了如何在项目中引入Guice,配置Module,以及如何使用`Injector`创建和管理对象。 通过阅读这篇博客,读者应该能够理解Guice的基本概念,学会如何在自己...
《Java Web典型模块与项目实战大全(程序员典藏)》以实战开发为原则,以Java EE主流框架整合应用及项目开发为主线,通过Java Web开发中最常见的19个典型模块和5个完整的项目案例,详细介绍了Struts 2.x、Spring、...
《Java Web典型模块与项目实战大全》以实战开发为原则,以Java EE主流框架整合应用及项目开发为主线,通过Java Web开发中最常见的19个典型模块和5个完整的项目案例,详细介绍了Struts 2.x、Spring、Guice、Hibernate...
典型模型与项目实战大全>> 出版社: 清华大学出版社; 第1版 (2011年1月1日) 平装: 922页 由于上传限制共分成4卷 请手动搜索其它3卷下载 或点击上传者的链接可直接查到 第1篇 开发工具及框架概述 第1章 开发前奏 第2...
Guice支持自定义绑定器,允许开发者根据项目需求定制依赖注入行为,从而增强了框架的灵活性和适应性。 #### 3. 高效性 Guice在运行时生成对象图的速度非常快,几乎不会对应用性能造成任何影响,这使其成为大规模...
典型模型与项目实战大全>> 出版社: 清华大学出版社; 第1版 (2011年1月1日) 平装: 922页 由于上传限制共分成4卷 下面是其它三卷的链接 第二卷: http://download.csdn.net/detail/jincheng52rmb/5349256 第三卷: ...
典型模型与项目实战大全>> 出版社: 清华大学出版社; 第1版 (2011年1月1日) 平装: 922页 由于上传限制 共分成4卷 请手动搜索其它3卷下载 第1篇 开发工具及框架概述 第1章 开发前奏 第2章 MyEclipSO开发工具对各种...
典型模型与项目实战大全>> 出版社: 清华大学出版社; 第1版 (2011年1月1日) 平装: 922页 由于上传限制共分成4卷 请手动搜索其它3卷下载 或点击上传者的链接可直接查到 第1篇 开发工具及框架概述 第1章 开发前奏 第2...
java实战开发1200例源码网片 Codecov.io / jacoco 有两个bug,一个与聚合报告有关(所以我们实际上高于这个数字) 很难缩小我最喜欢的 5 个功能的范围,但可以尝试一下 你可以在不分叉 git repo 的情况下修复 ...
本项目“ioc-dojo”是一个实战示例,旨在帮助开发者理解如何在Java应用中运用IOC和依赖注入。通过这个项目,你可以学习到: 1. **依赖注入的基本概念**:了解依赖是如何通过构造函数、setter方法或者注解形式被注入...
#### 经典项目实战 - **银行账户管理系统**:利用Struts 2 + Spring + Hibernate构建一个完整的银行账户管理系统,涵盖账户管理、转账等功能。 - **购物车功能**:使用Struts 2 + Guice + JPA实现一个购物车功能,...
- **Google Guice**:Google 提供的一个轻量级 DI 框架。 - **Jdon Framework**:提供了一系列企业级应用开发工具。 - **1.12 小结** - **总结**:介绍了 Spring 框架的基本概念、新功能以及生态系统。 #### 第...
- **Google Guice**:由 Google 开发的轻量级依赖注入框架,简化了依赖注入的过程,尤其适合那些希望减少配置工作量的项目。Guice 支持注解驱动的绑定方式,易于上手且功能强大。 - **PicoContainer**:一个简单且...
10. **实战应用**:GuiceBillingServiceDemo项目展示了如何在实际的计费服务场景中使用Guice,包括如何设计接口,如何编写模块,如何进行依赖注入等,有助于学习Guice的实际应用。 通过这个项目,开发者可以深入...