1、什么是Spring框架?Spring框架有哪些主要模块?
- spring目标是简化企业级开发的技术框架
- 主要模块有:核心容器,数据访问/集成,Web,AOP,工具,消息和测试模块
2、使用Spring框架有什么好处?
下面列举了一些使用Spring框架带来的主要好处:
- Dependency Injection(DI) 方法使得构造器和JavaBean properties文件中的依赖关系一目了然。
- 与EJB容器相比较,IoC容器更加趋向于轻量级。这样一来IoC容器在有限的内存和CPU资源的情况下进行应用程序的开发和发布就变得十分有利。
- Spring并没有闭门造车,Spring利用了已有的技术比如ORM框架、logging框架、J2EE、Quartz和JDK Timer,以及其他视图技术。
- Spring框架是按照模块的形式来组织的。由包和类的编号就可以看出其所属的模块,开发者仅仅需要选用他们需要的模块即可。
- 要测试一项用Spring开发的应用程序十分简单,因为测试相关的环境代码都已经囊括在框架中了。更加简单的是,利用JavaBean形式的POJO类,可以很方便的利用依赖注入来写入测试数据。
- Spring的Web框架亦是一个精心设计的Web MVC框架,为开发者们在web框架的选择上提供了一个除了主流框架比如Struts、过度设计的、不流行web框架的以外的有力选项。
- Spring提供了一个便捷的事务管理接口,适用于小型的本地事物处理(比如在单DB的环境下)和复杂的共同事物处理(比如利用JTA的复杂DB环境)。
3、什么是控制反转(IOC)?什么是依赖注入?
IOC是一种编程思想,用于指导我们如何设计出一个松耦程序。在spring框架中,有了IOC容器后,把__创建和查找依赖对象的控制权交给容器__,容器进行注入组合对象,所以对象和对象之间是松耦合的,这样也__方便测试,利于功能复用__,更重要的是使得程序的整个体系结构变得非常灵活
DI:Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。,
4、请解释下Spring中的IOC?
IOC是一种编程思想,用于指导我们如何设计出一个松耦程序。在spring框架中,有了IOC容器后,把__创建和查找依赖对象的控制权交给容器__,容器进行注入组合对象,所以对象和对象之间是松耦合的,这样也__方便测试,利于功能复用__,更重要的是使得程序的整个体系结构变得非常灵活
5、BeanFactory和ApplicationContext有什么区别?
BeanFactory
BeanFactory是spring的原始接口,针对原始结构的实现类功能比较单一,BeanFactory接口实现的容器,特点是在每次获取对象时才会创建对象。
ApplicationContext
继承了BeanFactory接口,拥有BeanFactory的全部功能,并且扩展了很多高级特性,每次容器启动时就会创建所有的对象。
创建ApplicationContext的方法:
- 丛类路径下加载配置文件:ClassPathXmlApplicationContext (“applicationContext.xml”);
- 从硬盘绝对路径下加载配置文件: FileSystemXmlApplicationContext(“d:/xxx/yyy/xxx”);
6、将Spring配置到你的应用中共有几种方法?
将Spring配置到应用开发中有以下三种方式:
- 基于XML的配置
- 基于注解的配置
- 基于Java的配置
7、什么基于XML的配置?
在Spring框架中,依赖和服务需要在专门的配置文件来实现,我常用的XML格式的配置文件。这些配置文件的格式通常用开头,然后一系列的bean定义和专门的应用配置选项组成。 SpringXML配置的主要目的时候是使所有的Spring组件都可以用xml文件的形式来进行配置。这意味着不会出现其他的Spring配置类型(比如声明的方式或基于Java Class的配置方式) Spring的XML配置方式是使用被Spring命名空间的所支持的一系列的XML标签来实现的。Spring有以下主要的命名空间:context、beans、jdbc、tx、aop、mvc和aso。
8、什么基Java的配置?
Spring对Java配置的支持是__由@Configuration注解和@Bean注解来实现__的。由__@Bean注解的方法将会实例化、配置和初始化一个新对象__,这个对象将由Spring的IoC容器来管理。被@Configuration所注解的类则表示这个类的主要目的是作为bean定义的资源。被@Configuration声明的类可以通过在同一个类的内部调用@bean方法来设置嵌入bean的依赖关系。
9、怎样用注解的方式配置Spring?
Spring在2.5版本以后开始支持用注解的方式来配置依赖注入。可以用注解的方式来替代XML方式的bean描述,可以将bean描述转移到组件类的内部,只需要在相关类上、方法上或者字段声明上使用注解即可。注解注入将会被容器在XML注入之前被处理,所以后者会覆盖掉前者对于同一个属性的处理结果。 注解装配在Spring中是默认关闭的。所以需要在Spring文件中配置一下才能使用基于注解的装配模式。如果你想要在你的应用程序中使用关于注解的方法的话,请参考如下的配置。
在 标签配置完成以后,就可以用注解的方式在Spring中向属性、方法和构造方法中自动装配变量。 下面是几种比较重要的注解类型:
- @Required:该注解应用于设值方法。
- @Autowired:该注解应用于有值设值方法、非设值方法、构造方法和变
- @Qualifier:该注解和@Autowired注解搭配使用,用于消除特定bean自动装配的歧义。
- JSR-250 Annotations:Spring支持基于JSR-250 注解的以下注解,@Resource、@PostConstruct 和 @PreDestroy。
10、描述Spring Bean的生命周期?
Spring Bean的生命周期简单易懂。在一个bean实例被初始化时,需要执行一系列的初始化操作以达到可用的状态。同样的,当一个bean不在被调用时需要进行相关的析构操作,并从bean容器中移除。 Spring bean factory 负责管理在spring容器中被创建的bean的生命周期。Bean的生命周期由两组回调(call back)方法组成。
-
初始化之后调用的回调方法。
-
销毁之前调用的回调方法。
- Spring框架提供了以下四种方式来管理bean的生命周期事件:
- InitializingBean和DisposableBean回调接口
- 针对特殊行为的其他Aware接口
- Bean配置文件中的Custom init()方法和destroy()方法
- @PostConstruct和@PreDestroy注解方式 使用customInit()和 customDestroy()方法管理bean生命周期的代码样例如下
11、描述Spring中各种Bean的范围?
1,singleton Spring ioc 容器中仅有一个 Bean 实例,Bean 以单例的方式存在;(默认)
2,prototype 每次从容器中调用 Bean 时,都返回一个新的实例;
3,request 每次 HTTP 请求都会创建一个新的 Bean;
4,session 同一个 HTTP Session 共享一个 Bean;
5,global session 同一个全局 Session 共享一个 Bean,一般用于 Portlet 应用环境;
6,application 同一个 Application 共享一个 Bean
12、什么是Spring的嵌入beans?
在spring的配置文件中,命名空间, 对于嵌入式的beans标签,想信大家很少使用过,或者接触过,起码,我本人就没用过. 它非常类似于Import标签所提供的功能;
13、Spring框架中的单例bean是否是线程安全的?
线程安全这个问题,要从单例与原型Bean分别进行说明。
原型Bean 对于原型Bean,每次创建一个新对象,也就是线程之间并不存在Bean共享,自然是不会有线程安全的问题。
单例Bean 对于单例Bean,所有线程都共享一个单例实例Bean,因此是存在资源的竞争。
无状态Bean,也就是线程中的操作不会对Bean的成员执行查询以外的操作,那么这个单例Bean是线程安全的。比如Spring mvc 的 Controller、Service、Dao等,这些Bean大多是无状态的,只关注于方法本身。
有状态对象(Stateful Bean) :就是有实例变量的对象,可以保存数据,是非线程安全的
- 在类中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在 ThreadLocal 中(推荐的一种方式)。
14、请举例说明如何用Spring注入一个Java的集合类?
<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>
15、请举例说明如何在Spring的Bean中注入一个java.util.Properties?
<bean id="adminUser" class="com.howtodoinjava.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>
16、请解释Spring的Bean的自动生成原理?
第一步:解析XML
第二步:获取每个Bean的Class
第三步:利用反射对Bean的私有属性赋值
17、请解释自动装配模式的区别?
在Spring框架中共有__5种自动装配__,让我们逐一分析。
-
no:这是Spring框架的默认设置,在该设置下自动装配是关闭的,开发者需要自行在bean定义中用标签明确的设置依赖关系。
-
byName:该选项可以根据bean名称设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的名称自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。
-
byType:该选项可以根据bean类型设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的类型自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。
-
constructor:造器的自动装配和byType模式类似,但是仅仅适用于与有构造器相同参数的bean,如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。
-
autodetect:该模式自动探测使用构造器自动装配或者byType自动装配。首先,首先会尝试找合适的带参数的构造器,如果找到的话就是用构造器自动装配,如果在bean内部没有找到相应的构造器或者是无参构造器,容器就会自动选择byTpe的自动装配方式。
18、如何开启基于基于注解的自动写入?
@Resource注解方式进行装配,默认按名称装配,当找不到与名称匹配的bean才会按类型装配 @Autowired自动装配具有兼容类型的单个bean属性。可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。通过@Autowied的使用来代替set方法。(property属性通过调用setter进行赋值)
19、请举例说明@Required注解?
@Required注解应用于bean属性的setter方法,它表明影响的bean属性在配置时必须放在XML配置文件中。
当被@Required的set方法,在xml中没有被设置,活抛出 BeanInitializationException
的异常
20、请举例说明@Autowired注解?
使用 @Autowired 注解进行装配,
- 只能是根据类型进行匹配。
- @Autowired 注解可以用于 Setter 方法、构造函数、字段,甚至普通方法,前提是方法必须有至少一个参数。
- @Autowired 可以用于数组和使用泛型的集合类型。然后 Spring 会将容器中所有类型符合的 Bean 注入进来。@Autowired 标注作用于 Map 类型时,如果 Map 的 key 为 String 类型,则 Spring 会将容器中所有类型符合 Map 的 value 对应的类型的 Bean 增加进来,用 Bean 的 id 或 name 作为 Map 的 key
21、请举例说明@Qualifier注解?
当同一个Class被在bean初始化多次时,我们需要明确的注入我们想要的bean,可以通过一下两个方法
1.@Qualifier(name=”????”) 和@Autowired 配合使用
2.通过@Resource 的方式,因为 @Resource可通过beanID示例化
22、请说明构造器注入和setter方法注入之间的区别?
set设值注入有如下优点
- 设值注入需要该Bean包含这些属性的setter方法
- 与传统的JavaBean的写法更相似,程序开发人员更容易理解、接收。通过setter方法设定依赖关系显得更加只管。
- 对于复杂的依赖关系,如果采用构造注入,会导致构造器国语臃肿,难以阅读。Spring在创建Bean实例时,需要同时实例化器依赖的全部实例,因而导致性能下降。而使用设值注入,则能避免这些问题
- 尤其是在某些属性可选的情况况下,多参数的构造器显得更加笨重
构造注入有以下优势
- 构造注入需要该Bean包含带有这些属性的构造器
- 构造注入可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入。例如,组件中其他依赖关系的注入,常常要依赖于DataSrouce的注入。采用构造注入,可以在代码中清晰的决定注入顺序。
- 对于依赖关系无需变化的Bean,构造注入更有用处。因为没有Setter方法,所有的依赖关系全部在构造器内设定。因此,无需担心后续的代码对依赖关系产生破坏。
- 依赖关系只能在构造器中设定,则只有组件的创建者才能改变组件的依赖关系。对组件的调用者而言,组件内部的依赖关系完全透明,更符合高内聚的原则。
23、Spring框架中有哪些不同类型的事件?
Spring的ApplicationContext 提供了__支持事件__和__代码中监听器__的功能。
我们可以创建bean用来监听在ApplicationContext 中发布的事件。ApplicationEvent类和在ApplicationContext接口中处理的事件,如果一个bean实现了ApplicationListener接口,当一个ApplicationEvent 被发布以后,bean会自动被通知。
public class AllApplicationEventListener implements ApplicationListener < ApplicationEvent >
{
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent)
{
//process event
}
}
Spring 提供了以下5中标准的事件:
-
上下文更新事件(ContextRefreshedEvent):该事件会在ApplicationContext被初始化或者更新时发布。也可以在调用ConfigurableApplicationContext 接口中的refresh()方法时被触发。
-
上下文开始事件(ContextStartedEvent):当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。
-
上下文停止事件(ContextStoppedEvent):当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。
-
上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。
-
请求处理事件(RequestHandledEvent):在Web应用中,当一个http请求(request)结束触发该事件。
除了上面介绍的事件以外,还可以通过扩展ApplicationEvent 类来开发自定义的事件。
public class CustomApplicationEvent extends ApplicationEvent
{
public CustomApplicationEvent ( Object source, final String msg )
{
super(source);
System.out.println("Created a Custom event");
}
}
为了监听这个事件,还需要创建一个监听器:
public class CustomEventListener implements ApplicationListener < CustomApplicationEvent >
{
@Override
public void onApplicationEvent(CustomApplicationEvent applicationEvent) {
//handle event
}
}
之后通过applicationContext接口的publishEvent()方法来发布自定义事件。
CustomApplicationEvent customEvent = new CustomApplicationEvent(applicationContext, “Test message”);
applicationContext.publishEvent(customEvent);
24、FileSystemResource和ClassPathResource有何区别?
在FileSystemResource 中需要给出spring-config.xml文件在你项目中的相对路径或者绝对路径。在ClassPathResource中spring会在ClassPath中自动搜寻配置文件,所以要把ClassPathResource 文件放在ClassPath下。
如果将spring-config.xml保存在了src文件夹下的话,只需给出配置文件的名称即可,因为src文件夹是默认。
简而言之,ClassPathResource在环境变量中读取配置文件,FileSystemResource在配置文件中读取配置文件。
25、请列举Spring框架中用了哪些设计模式
Spring框架中使用到了大量的设计模式,下面列举了比较有代表性的:
-
代理模式—在AOP和remoting中被用的比较多。
-
单例模式—在spring配置文件中定义的bean默认为单例模式。
-
模板方法—用来解决代码重复的问题。
-
比如. RestTemplate, JmsTemplate, JpaTemplate。
-
前端控制器—Srping提供了DispatcherServlet来对请求进行分发。
-
视图帮助(View Helper )—Spring提供了一系列的JSP标签,高效宏来辅助将分散的代码整合在视图里。
-
依赖注入—贯穿于BeanFactory / ApplicationContext接口的核心理念。
-
工厂模式—BeanFactory用来创建对象的实例。