目录
Spring篇
1、Spring Bean的作用域之间有什么区别?
2、什么是Spring inner beans?
3、Spring框架中的单例Beans是线程安全的吗?
4、请举例说明如何在Spring中诸如一个Java Collection?
5、如何向Spring Bean中诸如一个Java.util.Properties?
6、 请解释Spring Bean的自动装配?
7、请解释自动装配模式的区别?
8、如何开启基于注解的自动装配?
9、请举例解释@Required注解
10、请举例解释@Autowired注解
Spring篇
1、Spring Bean的作用域之间有什么区别?
Spring 容器中的 bean 可以分为 5 个范围。所有范围的名称都是自说明的,但是为了避免混淆,还是让我们来解释一下:
- singleton:这种 bean 范围是默认的,这种范围确保不管接受到多少个请求,每个容器中只有一个bean 的实例,单例的模式由 bean factory 自身来维护。
- prototype:原形范围与单例范围相反,为每一个 bean 请求提供一个实例。
- request:在请求 bean 范围内会每一个来自客户端的网络请求创建一个实例,在请求完成以后,bean 会失效并被垃圾回收器回收。
- Session:与请求范围类似,确保每个 session 中有一个 bean 的实例,在 session 过期后,bean会随之失效。
- global- session:global-session 和 Portlet 应用相关。当你的应用部署在 Portlet 容器中工作时,它包含很多 portlet。如果 你想要声明让所有的 portlet 共用全局的存储变量的话,那么这全局变量需要存储在 global-session 中。
全局作用域与 Servlet 中的 session 作用域效果相同。
2、什么是Spring inner beans?
在 Spring 框架中,无论何时 bean 被使用时,当仅被调用了一个属性。一个明智的做法是将这个bean 声明为内部 bean 。内部 bean 可以用 setter 注入 “ 属性 ” 和构造方法注入 “ 构造参数 ” 的方式来实现。比如,在我们的应用程序中,一个 Customer 类引用了一个 Person 类,我们的要做的是创建一个Person 的实例,然后在 Customer 内部使用。public class Customer{ private Person person; //Setters and Getters } public class Person{ private String name; private String address; private int age; //Setters and Getters }
内部 bean 的声明方式如下:<bean id="CustomerBean" class="com.somnus.common.Customer"> <property name="person"> <!-- This is inner bean --> <bean class="com.howtodoinjava.common.Person"> <property name="name" value="lokesh" /> <property name="address" value="India" /> <property name="age" value="34" /> </bean> </property> </bean>
3、Spring框架中的单例Beans是线程安全的吗?
Spring 框架并没有对单例 bean 进行任何多线程的封装处理。关于单例 bean 的线程安全和并发问题需要开发者自行去搞定。但实际上,大部分的 Spring bean 并没有可变的状态 ( 比如 Serview 类和 DAO 类 ) ,所以在某种程度上说 Spring 的单例 bean 是线程安全的。如果你的 bean 有多种状态的话(比如 View Model 对象),就需要自行保证线程安全。最浅显的解决办法就是将多态 bean 的作用域由 “singleton” 变更为 “prototype” 。
4、请举例说明如何在Spring中诸如一个Java Collection?
Spring 提供了以下四种集合类的配置元素:
- <list> : 该标签用来装配可重复的 list 值。
- <set> : 该标签用来装配没有重复的 set 值。
- <map>: 该标签可用来注入键和值可以为任何类型的键值对。
- <props> : 该标签支持注入键和值都是字符串类型的键值对。
下面看一下具体的例子:
<beans> <!-- Definition for javaCollection --> <bean id="javaCollection" class="com.howtodoinjava.JavaCollection"> <!-- java.util.List --> <property name="customList"> <list> <value>INDIA</value> <value>Pakistan</value> <value>USA</value> <value>UK</value> </list> </property> <!-- java.util.Set --> <property name="customSet"> <set> <value>INDIA</value> <value>Pakistan</value> <value>USA</value> <value>UK</value> </set> </property> <!-- java.util.Map --> <property name="customMap"> <map> <entry key="1" value="INDIA"/> <entry key="2" value="Pakistan"/> <entry key="3" value="USA"/> <entry key="4" value="UK"/> </map> </property> <!-- java.util.Properties --> <property name="customProperies"> <props> <prop key="admin">admin@nospam.com</prop> <prop key="support">support@nospam.com</prop> </props> </property> </bean> </beans>
5、如何向Spring Bean中诸如一个Java.util.Properties?
第一种方法是使用如下面代码所示的<props> 标签:
<bean id="adminUser" class="com.somnus.common.Customer"> <!-- java.util.Properties --> <property name="emails"> <props> <prop key="admin">admin@nospam.com</prop> <prop key="support">support@nospam.com</prop> </props> </property> </bean>
也可用 ”util:” 命名空间来从 properties 文件中创建出一个 propertiesbean ,然后利用 setter 方法注入 bean 的引用。
6、 请解释Spring Bean的自动装配?
在 Spring 框架中,在配置文件中设定 bean 的依赖关系是一个很好的机制, Spring 容器还可以自动装配合作关系 bean 之间的关联关系。这意味着 Spring 可以通过向 Bean Factory 中注入的方式自动搞定 bean 之间的依赖关系。自动装配可以设置在每个 bean 上,也可以设定在特定的 bean上。下面的 XML 配置文件表明了如何根据名称将一个 bean 设置为自动装配:<bean id="employeeDAO" class="com.howtodoinjava.EmployeeDAOImpl" autowire="byName" />
除了 bean 配置文件中提供的自动装配模式,还可以使用 @Autowired 注解来自动装配指定的 bean。在使用@Autowired 注解之前需要在按照如下的配置方式在 Spring 配置文件进行配置才可以使用。<context:annotation-config />
也可以通过在配置文件中配置 AutowiredAnnotationBeanPostProcessor 达到相同的效果。
<bean class ="org.springframework.beans.factory.annotation.AutowiredAnnotationBea nPostProcessor"/>
配置好以后就可以使用 @Autowired 来标注了。@Autowired public EmployeeDAOImpl ( EmployeeManager manager ) { this.manager = manager; }
7、请解释自动装配模式的区别?
Spring 框架中共有 5 种自动装配,让我们逐一分析。1. no :这是 Spring 框架的默认设置,在该设置下自动装配是关闭的,开发者需要自行在 bean 定义中用标签明确的设置依赖关系。2. byName :该选项可以根据 bean 名称设置依赖关系。当向一个 bean 中自动装配一个属性时,容器将根据 bean 的名称自动在在配置文件中查询一个匹配的 bean 。如果找到的话,就装配这个属性,如果没找到的话就报错。3. byType :该选项可以根据 bean 类型设置依赖关系。当向一个 bean 中自动装配一个属性时,容器将根据 bean 的类型自动在在配置文件中查询一个匹配的 bean 。如果找到的话,就装配这个属性,如果没找到的话就报错。4. constructor :造器的自动装配和 byType 模式类似,但是仅仅适用于与有构造器相同参数的bean,如果在容器中没有找到与构造器参数类型一致的 bean ,那么将会抛出异常。5. autodetect :该模式自动探测使用构造器自动装配或者 byType 自动装配。首先,首先会尝试找合适的带参数的构造器,如果找到的话就是用构造器自动装配,如果在 bean 内部没有找到相应的构造器或者是无参构造器,容器就会自动选择 byTpe 的自动装配方式。
8、如何开启基于注解的自动装配?
要使用 @Autowired,需要注册 AutowiredAnnotationBeanPostProcessor,可以有以下两种方式来实现:1 、引入配置文件中的 <bean> 下引入 <context:annotation-config><beans> <context:annotation-config /> </beans>
2、在 bean 配置文件中直接引入 AutowiredAnnotationBeanPostProcessor
<beans> <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotati onBeanPostProcessor"/> </beans>
9、请举例解释@Required注解
在产品级别的应用中, IoC 容器可能声明了数十万了 bean , bean 与 bean 之间有着复杂的依赖关系。设值注解方法的短板之一就是验证所有的属性是否被注解是一项十分困难的操作。可以通过在<bean>中设置 “dependency-check” 来解决这个问题。在应用程序的生命周期中,你可能不大愿意花时间在验证所有 bean 的属性是否按照上下文文件正确配置。或者你宁可验证某个 bean 的特定属性是否被正确的设置。即使是用 “dependency check”属性也不能很好的解决这个问题,在这种情况下,你需要使用 @Required 注解。需要用如下的方式使用来标明 bean 的设值方法。private String designation; public String getDesignation() { return designation; } @Required public void setDesignation(String designation) { this.designation = designation; } //more code here }
RequiredAnnotationBeanPostProcessor 是 Spring 中的后置处理用来验证被@Required 注解的 bean 属性是否被正确的设置了。在使用RequiredAnnotationBeanPostProcesso 来验证 bean 属性之前,首先要在 IoC 容器中对其进行注册:<bean class="org.springframework.beans.factory.annotation.RequiredAnnotatio nBeanPostProcessor" />
但是如果没有属性被用 @Required 注解过的话,后置处理器会抛出一个 BeanInitializationException 异常。
10、请举例解释@Autowired注解
@Autowired 注解对自动装配何时何处被实现提供了更多细粒度的控制。@Autowired 注解可以像@Required 注解、构造器一样被用于在 bean 的设值方法上自动装配 bean的属性,一个参数或者带有任意名称或带有多个参数的方法。比如,可以在设值方法上使用@Autowired 注解来替代配置文件中的 <property>元素。当 Spring 容器在 setter 方法上找到@Autowired 注解时,会尝试用 byType自动装配。当然我们也可以在构造方法上使用@Autowired 注解。带有@Autowired 注解的构造方法意味着在创建一个 bean 时将会被自动装配,即便在配置文件中使用<constructor-arg> 元素 。public class TextEditor { private SpellChecker spellChecker; @Autowired public TextEditor(SpellChecker spellChecker){ System.out.println("Inside TextEditor constructor." ); this.spellChecker = spellChecker; } public void spellCheck(){ spellChecker.checkSpelling(); } }
下面是没有构造参数的配置方式:<beans> <context:annotation-config/> <!-- Definition for textEditor bean without constructor-arg --> <bean id="textEditor" class="com.howtodoinjava.TextEditor"/> <!-- Definition for spellChecker bean --> <bean id="spellChecker" class="com.howtodoinjava.SpellChecker"/> </beans>