浏览 4513 次
锁定老帖子 主题:【转】Spring 学习笔记--强烈推荐
该帖已经被评为隐藏帖
|
|
---|---|
作者 | 正文 |
发表时间:2008-04-16
* 阅前说明: * 此文件为笔者在学习Spring时所写的一些笔记<br> * 希望能抛砖引玉来促进大家以各种方式交流学习心得<br> * 如有转载,为了尊重笔者的劳动成果,请保留此段说明<br> * @author 贺小佼 HeXiaojiao<br> * Email ld_hxj1@yahoo.com.cn <br> * QQ 88137099<br> * Time 2008-04-14 16:43:43 <br> * Blog http://blog.csdn.net/hexiaojiao */ Day-01 问题提出: 框架的主要优势是什么? 请简要描述Spring? Spring框架分为哪几个模块,请详述? Spring有哪些注入方式,请详细描述? 1.在Setter注入方式中,在beans包下的ProductBean中只加入一个带参数的构造 方法会如何? 2.在config.xml中少加一property项会如何? 3.Spring中有哪些集合注入,如何注入? 4.问:如何设置单例模式?有什么作用和特殊效果? 5.问:什么叫混合注入模式,请举例说明? 6.问: Spring中如何进行类型数据的设置 7.问:Spring支不支持数据类型自动转换?构造器复杂情况有哪些? 8.问:如果为嵌套属性(其属性为一个类)时如果配置?(Bean的引用如果配置) 9.问:Bean初始化方案有哪几种,请详述? 10.问:在bean类中(1)初始化接口方案、(2)构造方法与(3)初始化方法方案中各 方法的执行顺序如何? //======================================================= 问题解决: //------------------------------------------------------------------- ---------- 框架的主要优势是什么? 请简要描述Spring? Spring框架分为哪几个模块,请详述? 答:Spring框架可分为七个模块,分别如下: 1.核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组 件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。 2.Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供 上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际 化、校验和调度功能。 3.Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的 编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的 任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供 了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性 事务管理集成到应用程序中。 4.Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该 结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了 错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接) 。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。 5.Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都 遵从 Spring 的通用事务和 DAO 异常层次结构。 6.Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上, 为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对 象的工作。 7.Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术 ,其中包括 JSP、Velocity、Tiles、iText 和 POI。 //------------------------------------------------------------------- ---------- Spring有哪些注入方式,请详细描述? 答: 通过注入方式,使程序解耦合 一。通过构造器(构造方法)注入 构造器注入操作步骤: 1.引入Spring架包,建包ioc.common 在这包下建立三个包 ioc.common.beans,ioc.common.config,ioc.common.logic 2.在beans包下建立UserBean类,代码如下: //UserBean.java package ioc.common.beans; public class UserBean { private String userName; private String userPassword; public UserBean() { } public UserBean(String userName, String userPassword) { this.userName = userName; this.userPassword = userPassword; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPassword() { return userPassword; } public void setUserPassword(String userPassword) { this.userPassword = userPassword; } @Override public String toString() { return userName + "-" + userPassword; } } 3.在config包下建立config.xml文件,内容如下: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="userBean" class="ioc.common.beans.UserBean"> <constructor-arg index="0"> <value>Janet </value> </constructor-arg> <constructor-arg index="1"> <value>88888888</value> </constructor-arg> </bean> </beans> 4.在logic包下建立Run.java,内容如下: package ioc.common.logic; import ioc.common.beans.UserBean; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class Run { public static void main(String[] args) { String fileName = "./src/ioc/common/config/config.xml"; ApplicationContext ac = new FileSystemXmlApplicationContext (fileName); // 取得一个实例 UserBean user = (UserBean) ac.getBean("userBean"); System.out.println(user); } } //end of Run.java 框架:有固定流程的代码集合,代码中的流程能被反复重用 备注: 1、如果构造器(方法)中没有写任何代码又会如何? 答:将会输出 null-null,Spring不关心构造器实现何种功能,只去调用执行; 2、如果没有这个构造器会如何? 答:将会使Spring找不到该构造器而产生异常 Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userBean' defined in file [/home/tarena/corejava/JSP/SpringPrj/./src/ioc/common/config/config.xm l]: 2 constructor arguments specified but no matching constructor found in bean 'userBean' (hint: specify index and/or type arguments for simple parameters to avoid type ambiguities) 3、如果构造器中有多个参数,没有配置其中某个参数会如何?如何处理? 答:Spring将会产生找不到参数异常,处理方式:建立一个没有该参数的构造 器或写入参数 Related cause: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userBean' defined in file [/home/tarena/corejava/JSP/SpringPrj/./src/ioc/common/config/config.xm l]: Unsatisfied dependency expressed through constructor argument with index 1 of type [java.lang.String]: Ambiguous constructor argument types - did you specify the correct bean references as constructor arguments? Context:包含特定内容的环境 /////////////////////////////////////////////Constructor IOC END 二。 Set注入 1.在步骤一的基础上,在beans包下建立ProductBean类,代码如下: //ProductBean.java package ioc.common.beans; public class ProductBean { private String productName; private String productDiscript; public void setProductName(String productName) { this.productName = productName; } public void setProductDiscript(String productDiscript) { this.productDiscript = productDiscript; } @Override public String toString() { return productName + "-" + productDiscript; } } 2.在config.xml中加入如下内容: <bean id="productBean" class="ioc.common.beans.ProductBean"> <property name="productName"> <value>Motorolla</value> </property> <property name="productDiscript"> <value>mebophone producter</value> </property> </bean> 3.在logic包下新建类RunConstructor代码如下 //RunSetter.java package ioc.common.logic; import ioc.common.beans.ProductBean; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class RunSetter { public static void main(String[] args) { String fileName = "./src/ioc/common/config/config.xml"; ApplicationContext ac = new FileSystemXmlApplicationContext (fileName); ProductBean product = (ProductBean) ac.getBean ("productBean"); System.out.println(product); } } 问题: 1.在Setter注入方式中,在beans包下的ProductBean中只加入一个带参 数的构造方法会如何? 答:将会产生异常Spring异常与JVM异常 Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'productBean' defined in file [/home/tarena/corejava/JSP/SpringPrj/./src/ioc/common/config/config.xm l]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [ioc.common.beans.ProductBean]: No default constructor found; nested exception is java.lang.NoSuchMethodException: ioc.common.beans.ProductBean.<init>() //JVM异常 Caused by: java.lang.NoSuchMethodException: ioc.common.beans.ProductBean.<init>() Tips:强烈建议有不带参数的构造器 2.在config.xml中少加一property项会如何? 答:正常运行,但少加的属性值为null; 3.Spring中有哪些集合注入,如何注入? 答: Spring中有List,Map,Properties,Set,数组(如 String [] ,使用 同List)等集合注入; 注入方法: 在配置文件中<property name="变量名"> 或constructor-arg index="参数序号,从0开始取"加入相应配置参数 形如: <list> <value>Eric</value> <value>Narci</value> </list> <map> <entry key="HR"> <value>人力资源部</value> </entry> <entry key="MIS"> <value>信息管理部</value> </entry> </map> <props> <prop key="GG">成俊杰</prop> <prop key="MM">伍欣</prop> </props> <set> <value>CoreJava</value> <value>JDBC</value> <value>AJAX</value> </set> ////////////// END Set注入 END 三、 混合注入 即构造器注入与Set注入方式混合使用 如问题 5. Tips:如果同时在constractor-arg 和property标签中配置同一属性, 则Setter注入方式会覆盖构造器注入 //----------------------------------------------------------- 4.问:如何设置单例模式?有什么作用和特殊效果? 答:在config.xml中设置<bean id="userBean" class="bean_manager.beans.User" singleton="true"> 其中singleton="true",设定该bean为单例模式; 作用:调用该类的多个对象时只在第一次实例化 特殊效果: 调用时第一次创建对象并赋值,对象还在内存中存活, 在第二次或之后创建对象后不用赋值也能调用前面赋予的属性 值。 //------------------------------------------------------------------- ---------- 5.问:什么叫混合注入模式,请举例说明? 答:混合注入模式如: <constructor-arg index="0"> <value>Janet </value> </constructor-arg> <property name="userPassword"> <null /> </property> 这在构造器中设置用户名,而在Set注入中设置密码 //------------------------------------------------------------------- ---------- 6.问: Spring中如何进行类型数据的设置 答:在配置文件config.xml中进行设置,在value标签中加入属性type="类型" <property name="brithday"> <value type=”int”>500</value> </property> //------------------------------------------------------------------- ---------- 7.问:Spring支不支持数据类型自动转换?构造器复杂情况有哪些? 答:支持;如果构造器中参数个数与设置个数相等则调用String参数的构造器, 否则自动转换类型再进行调用 如果类型转换失败,则会输出相应出错信息。 //------------------------------------------------------------------- ---------- 8.问:如果为嵌套属性(其属性为一个类)时如果配置?(Bean的引用如果配置) 答:配置属性形如: <property name="product"> <ref bean="product"/><!--bean名为此配置文件中的另一个(引用类 的)bean中id属性值--> </property> <property name="brithday"> <ref bean="date"/> </property> <bean id="date" class="java.util.Date"></bean> //------------------------------------------------------------------- ---------- 9.问:Bean初始化方案有哪几种,请详述? 答:有初始化接口方案和初始化方法方案; 方案一:初始化接口方案如下: //Bean开发: package init.beans; public class User implements InitializingBean { private String userName; public void afterPropertiesSet () throws Exception { this.userName = "Google"; System.out.println("++++++++++++1"); } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } } config.xml的配置没有任何特殊的地方。如下: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="userBean" class="init.beans.UserBean"> <property name="userName"> <value>Eric</value> </property> </bean> </beans> 运行调用代码如下 init.logic.RunLogic.java package init.logic; import init.beans.UserBean; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class RunLogic { public static void main(String[] args) { String fileName = "./src/init/config/config.xml"; ApplicationContext ac = new FileSystemXmlApplicationContext (fileName); String beanName = "userBean"; Object obj = ac.getBean(beanName); if (obj != null) { UserBean user = (UserBean) obj; System.out.println(user.getUserName()); } } } //输出结果为 //++++++++++++1 方案二:初始化方法方案步骤如下: 1.在java Bean中加入初始化方法,形如: //init.beans.UserBean public String initUser() { this.userName = "BaiDu"; System.out.println("*******************2"); return this.userName; } 2.在配置文件./src/init/config/config.xml中写入如下内容: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="userBean" class="init.beans.UserBean" init-method="initUser"> <property name="userName"> <value>Eric</value> </property> </bean> </beans> 3.在调用类执行的方法中写入如下代码: //init.logic.RunLogic package init.logic; import init.beans.UserBean; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class RunLogic { public static void main(String[] args) { String fileName = "./src/init/config/config.xml"; ApplicationContext ac = new FileSystemXmlApplicationContext (fileName); String beanName = "userBean"; Object obj = ac.getBean(beanName); if (obj != null) { UserBean user = (UserBean) obj; System.out.println(user.getUserName()); } } } //得输出结果为: //*******************2 //BaiDu //------------------------------------------------------------------- ---------- 10.问:在bean类中(1)初始化接口方案、(2)构造方法与(3)初始化方法方案中 各方法的执行顺序如何? 答:执行顺序:为(2)==>(1)==>(3); 如在UserBean中加入: public UserBean() { System.out.println("#######################0"); } public String initUser() { this.userName = "BaiDu"; System.out.println("*******************2"); return this.userName; } public void afterPropertiesSet() throws Exception { this.userName = "Google"; System.out.println("++++++++++++1"); } //结果为: //#######################0 //++++++++++++1 //*******************2 //BaiDu //------------------------------------------------------------------- ---------- 什么叫依赖注入,控制反转? 依赖配置文件,通过配置文件来赋值,而不是在程序中 当bean某属性为数组时(如String [])如何配置? 答:类似List <property name="basenames"> <list> <value>international.config.resources</value> <!-- 可写多个资源文件 --> </list> </property> //------------------------------------------------------------------- ---------- //------------------------------------------------------------------- ---------- 如何对Spring进行国际化? 1).建立资源文件 // src/international/config/resources_zh_CN.properties中内容如 下: 引用 userinfo={0}\u662f\u4e00\u4e2a\u597d\u4eba // src/international/config/resources_en.properties中内容如下: userinfo={0} is a wonderful man 2).建立国际化配置文件 (src/international/config/config.xml) <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource "> <!-- id 与 class不能改动写死在Spring中类 FileSystemXmlApplicationContext 的getMessage方法中了 --> <property name="basenames"> <list> <value>international.config.resources</value> <!-- 可放多套资源文件,其中basenames为String [] 类型 --> </list> </property> </bean> </beans> 3).编写测试类(international.logic.Run) package international.logic; import java.util.Locale; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class Run { public static void main(String[] args) { String sourceFile = "src/international/config/config.xml"; ApplicationContext act = new FileSystemXmlApplicationContext(sourceFile); String resolvable = "userinfo"; Object[] paramList = { "Eric" }; String msg = act.getMessage(resolvable, paramList, Locale.getDefault()); // 如果为其他语言找不到其配置文件时,则会加载和操作系统语言一样 的资源文件 //如果也不存在则会出现异常 // 加载顺序 先加载指定语言资源 // 如果失败再尝试加载操作系统语言相应的资源文件 // 如果失败,再加载默认的资源文件 //一旦找到符合的就不再找了 //最后都找不到时抛出异常,不会加载此顺序外的资源文件 System.out.println(msg); } } //---------------------------------------END OF 如何对Spring进行国际化 ? 2.什么Spring事件模型请举例说明? 答: 事件模型包含三类角色,事件触发者,事件和事件接受者; 消息传递方向为,事件触发者==>事件==>事件接受者; 事件模型建立步骤: 1).定义事件 //event.events.WarnEvent package event.events; import org.springframework.context.ApplicationEvent; public class WarnEvent extends ApplicationEvent { private static final long serialVersionUID = 3287507907413175457L; public WarnEvent(Object source) { super(source); } } 2).建立事件响应者 //event.listeners.Receiver package event.listeners; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import event.events.WarnEvent; public class Receiver implements ApplicationListener { public void onApplicationEvent(ApplicationEvent event) { System.out.println("Receiver接收到事件@"); if (true == event instanceof WarnEvent) { // 对各种事件的处理 WarnEvent we = (WarnEvent) event; String msg = (String) we.getSource(); System.out.println("Receiver" + msg); } } } //------------------------------------------------------------------- --- //event.listeners.JaneReceiver package event.listeners; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import event.events.WarnEvent; public class JaneReceiver implements ApplicationListener { public void onApplicationEvent(ApplicationEvent event) { System.out.println("JaneReceiver接收到事件@"); if (true == event instanceof WarnEvent) { // 对各种事件的处理 WarnEvent we = (WarnEvent) event; long time = we.getTimestamp(); System.out.println("time" + time); String msg = (String) we.getSource(); System.out.println("JaneReceiver" + msg); } } } 3).建立配置文件// src/event/config/config.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="receiver" class="event.listeners.Receiver"></bean> <bean id="janereceiver" class="event.listeners.JaneReceiver"></bean> </beans> 4).建立事件触发者类 package event.sender; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; import event.events.WarnEvent; public class Run { public static void main(String[] args) { String sourceFile = "src/event/config/config.xml"; ApplicationContext act = new FileSystemXmlApplicationContext(sourceFile); WarnEvent event = new WarnEvent("HaHa"); act.publishEvent(event); } } //--------------------------------------2. END 3.问题:什么是AOP? 答:AOP全称是Aspect-Oriented Programming,中文翻译是面向方面的编程或 者面向切面的编程。 4.何谓Aspect? 答:Aspect(切面):一个关注点的模块化,这个关注点可能会横切多个对象。 事务管理是J2EE应用中一个关于横切关注点的很好的例子。 在SpringAOP中,切面可以使用通用类(基于模式的风格) 或者在普通类中以@Aspect注解(@Aspect风格)来实现。 即:当前关注的一个代码的流程,其中可能调用了多个类的多个方法。 5.请简述AOP的意义? 答:现在的系统往往强调减小模块之间的耦合度,AOP 技术就是用来帮助实现 这一目标的。 从某种角度上来讲“切面”是一个非常形象的描述,它好像在系统的功能之 上横切一刀, 要想让系统的功能继续,就必须先过了这个切面。 这些切面监视并拦截系统的行为,在某些(被指定的)行为执行之前或之后执行 一些附加的任务(比如记录日志). 而系统的功能流程(比如 Greeting)并不知道这些切面的存在, 更不依赖于这些切面,这样就降低了系统模块之间的耦合度。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |