Spring 总结以及在面试中的一些问题,java 面试笔试题代码
throwsBeansException{
System.out.println("第五步:后处理 Bean 的:before 初始化!!");
//后处理 Bean,在这里加上一个动态代理,就把这个 Bean 给修改了。
return bean;//返回 bean 本身,表示没有修改。
}
}
注意:这个前处理 Bean 和后处理 Bean 会对所有的 Bean 进行拦截。
⑥如果 Bean 实现 InitializingBean 执行 afterPropertiesSet
⑦调用<bean init-method="init"> 指定初始化方法 init
⑧如果存在类实现 BeanPostProcessor(处理 Bean) ,执行 postProcessAfterInitialization
⑨执行业务处理
⑩如果 Bean 实现 DisposableBean 执行 destroy
?调用<bean destroy-method="customerDestroy"> 指定销毁方法 customerDestroy
5.请介绍一下 Spring 框架中 Bean 的生命周期和作用域
(1)bean 定义
在配置文件里面用<bean></bean>来进行定义。
(2)bean 初始化
有两种方式初始化:
A.在配置文件中通过指定 init-method 属性来完成
B.实现 org.springframwork.beans.factory.InitializingBean 接口
(3)bean 调用
有三种方式可以得到 bean 实例,并进行调用
(4)bean 销毁
销毁有两种方式
A.使用配置文件指定的 destroy-method 属性
B.实现 org.springframwork.bean.factory.DisposeableBean 接口
##作用域
singleton
当一个 bean 的作用域为 singleton,?那么 Spring IoC 容器中只会存在一个共享的 bean 实例,并且所有对 bean 的请求,只要 id 与该 bean 定义相匹配,则只会返回 bean 的同一实例。
prototype
Prototype 作用域的 bean 会导致在每次对该 bean 请求(将其注入到另一个 bean 中,或者以程序的方式调用容器的 getBean()?方法)时都会创建一个新的 bean 实例。根据经验,对所有有状态的 bean 应该使用 prototype 作用域,而对无状态的 bean 则应该使用?singleton 作用域
request
在一次 HTTP 请求中,一个 bean 定义对应一个实例;即每次 HTTP 请求将会有各自的 bean 实例,?它们依据某个 bean 定义创建而成。该作用?域仅在基于 web 的 Spring ApplicationContext 情形下有效。
session
在一个 HTTP Session 中,一个 bean 定义对应一个实例。该作用域仅在基于 web 的 Spring ApplicationContext 情形下有效。
global session
在一个全局的 HTTP Session 中,一个 bean 定义对应一个实例。典型情况下,仅在使用 portlet context 的时候有效。该作用域仅在基于?web 的 Spring ApplicationContext 情形下有效。
6.Bean 注入属性有哪几种方式?
spring 支持构造器注入和 setter 方法注入
构造器注入,通过 <constructor-arg> 元素完成注入
setter 方法注入, 通过<property> 元素完成注入【开发中常用方式】
7.什么是 AOP,AOP 的作用是什么?
面向切面编程(AOP)提供另外一种角度来思考程序结构,通过这种方式弥补了面向对象编程(OOP)的不足,除了类(classes)以外,AOP 提供了切面。切面对关注点进行模块化,例如横切多个类型和对象的事务管理
Spring 的一个关键的组件就是 AOP 框架,可以自由选择是否使用 AOP 提供声明式企业服务,特别是为了替代 EJB 声明式服务。最重要的服务是声明性事务管理,这个服务建立在 Spring 的抽象事物管理之上。允许用户实现自定义切面,用 AOP 来完善 OOP 的使用,可以把 Spring AOP 看作是对 Spring 的一种增强
8.Spring 的核心类有哪些,各有什么作用?
BeanFactory:产生一个新的实例,可以实现单例模式
BeanWrapper:提供统一的 get 及 set 方法
ApplicationContext:提供框架的实现,包括 BeanFactory 的所有功能
9.Spring 里面如何配置数据库驱动?
使用”org.springframework.jdbc.datasource.DriverManagerDataSource”数据源来配置数据库驱动。示例如下:
<bean id=”dataSource”>
<property name=”driverClassName”>
<value>org.hsqldb.jdbcDriver</value>
</property>
<property name=”url”>
<value>jdbc:hsqldb:db/appfuse</value>
</property>
<property name=”username”><value>abc</value></property>
<property name=”password”><value>abc</value></property>
</bean>
10.Spring 里面 applicationContext.xml 文件能不能改成其他文件名?
ContextLoaderListener 是一个 ServletContextListener, 它在你的 web 应用启动的时候初始化。缺省情况下, 它会在 WEB-INF/applicationContext.xml 文件找 Spring 的配置。 你可以通过定义一个<context-param>元素名字为”contextConfigLocation”来改变 Spring 配置文件的 位置。示例如下:?
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/xyz.xml</param-value>
</context-param>
</listener-class>
</listener>
11.Spring 里面如何定义 hibernate mapping?
添加 hibernate mapping 文件到 web/WEB-INF 目录下的 applicationContext.xml 文件里面。示例如下:
<property name=”mappingResources”>
<list>
<value>org/appfuse/model/User.hbm.xml</value>
</list>
</property>
12.Spring 如何处理线程并发问题?
Spring 使用 ThreadLocal 解决线程安全问题
我们知道在一般情况下,只有无状态的 Bean 才可以在多线程环境下共享,在 Spring 中,绝大部分 Bean 都可以声明为 singleton 作用域。就是因为 Spring 对一些 Bean(如 RequestContextHolder、Transacti
onSynchronizationManager、LocaleContextHolder 等)中非线程安全状态采用 ThreadLocal 进行处理,让它们也成为线程安全的状态,因为有状态的 Bean 就可以在多线程中共享了。
ThreadLocal 和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。
在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。
而 ThreadLocal 则从另一个角度来解决多线程的并发访问。ThreadLocal 会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal 提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进 ThreadLocal。
由于 ThreadLocal 中可以持有任何类型的对象,低版本 JDK 所提供的 get()返回的是 Object 对象,需要强制类型转换。但 JDK5.0 通过泛型很好的解决了这个问题,在一定程度地简化 ThreadLocal 的使用。
概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而 ThreadLocal 采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。
13.为什么要有事物传播行为?
14.介绍一下 Spring 的事物管理
事务就是对一系列的数据库操作(比如插入多条数据)进行统一的提交或回滚操作,如果插入成功,那么一起成功,如果中间有一条出现异常,那么回滚之前的所有操作。这样可以防止出现脏数据,防止数据库数据出现问题。
开发中为了避免这种情况一般都会进行事务管理。Spring 中也有自己的事务管理机制,一般是使用 TransactionMananger 进行管?理,可以通过 Spring 的注入来完成此功能。spring 提供了几个关于事务处理的类:
TransactionDefinition //事务属性定义
TranscationStatus //代表了当前的事务,可以提交,回滚。
PlatformTransactionManager 这个是 spring 提供的用于管理事务的基础接口,其下有一个实现的抽象类?AbstractPlatformTransactionManager,我们使用的事务管理类例如?DataSourceTransactionManager 等都是这个类的子类。
一般事务定义步骤:
TransactionDefinition td =newTransactionDefinition();
TransactionStatus ts = transactionManager.getTransaction(td);
try{
//do sth
transactionManager.commit(ts);
}catch(Exception e){
transactionManager.rollback(ts);
}
spring 提供的事务管理可以分为两类:编程式的和声明式的。编程式的,比较灵活,但是代码量大,存在重复的代码比较多;声明式的比编程式的更灵活。
编程式主要使用 transactionTemplate。省略了部分的提交,回滚,一系列的事务对象定义,需注入事务管理对象.
void add(){
transactionTemplate.execute(newTransactionCallback(){
pulic Object doInTransaction(TransactionStatus ts){
//do sth
}
}
}
声明式:
使用 TransactionProxyFactoryBean:PROPAGATION_REQUIRED PROPAGATION_REQUIRED PROPAGATION_REQUIRED,readOnly
围绕 Poxy 的动态代理?能够自动的提交和回滚事务
评论