Spring Beans
答: Spring Beans
是那些形成Spring应用的主干的Java对象。它们被Spring IOC
容器初始化,装配和管理。这些Bean
通过容器中配置的元数据创建。比如,以XML
文件中的形式定义。
Spring
如何获取Bean
?ApplicationContext
对象;ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
ac.getBean("beanId");
Spring
提供的工具类(WebApplicationContextUtils
)获取**ApplicationContext
**对象;public String test(HttpServletRequest request,HttpServletRequest response) {
WebApplicationContext wc = RequestContextUtils.findWebApplicationContext(request);
wc.getBean("beanName");
WebApplicationContext wc2 = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext());
wc2.getBean("beanName");
}
ApplicationObjectSupport
;WebApplicationContext wac = (WebApplicationContext)servletContext
.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
WebApplicationObjectSupport
;ApplicationContextAware
;public class SpringContextUtil implements ApplicationContextAware {
// Spring应用上下文环境
private static ApplicationContext applicationContext;
/**
* 实现ApplicationContextAware接口的回调方法,设置上下文环境
*
* @param applicationContext
*/
public void setApplicationContext(ApplicationContext applicationContext) {
SpringContextUtil.applicationContext = applicationContext;
}
/**
* @return ApplicationContext
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 获取对象
*
* @param name
* @return Object
* @throws BeansException
*/
public static Object getBean(String name) throws BeansException {
return applicationContext.getBean(name);
}
}
Spring
提供的 ContextLoader
加载。WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
wac.getBean(beanID);
答: 元数据是指用来描述数据的数据,更通俗一点,就是描述代码间关系,或者代码与其他资源(例如数据库表)之间内在联系的数据。在一些技术框架,如struts
、EJB
、hibernate
就不知不觉用到了元数据。对struts
来说,元数据指的是struts-config.xml
;对EJB
来说,就是ejb-jar.xml
和厂商自定义的xml
文件;对hibernate
来说就是hbm
文件。以上阐述的几种元数据都是基于xml
文件的或者其他形式的单独配置文件。
ASCII
文件,没有显式的类型支持。基于元数据的广泛应用,JDK5.0
引入了Annotation
的概念来描述元数据。在Java
中,元数据以标签的形式存在于 Java
代码中,元数据标签的存在并不影响程序代码的编译和执行。
Annotation
就像代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取。读取到了程序元素的元数据,就可以执行相应的处理。通过注解,程序开发人员可以在不改变原有逻辑的情况下,在源代码文件中嵌入一些补充信息。代码分析工具、开发工具和部署工具可以通过解析这些注解获取到这些补充信息,从而进行验证或者进行部署等。
Spring Bean
定义包含什么?答: 一个Spring Bean
的定义包含容器必知的所有配置元数据,包括如何创建一个Bean
,它的生命周期详情及它的依赖。
Spring
容器提供配置元数据?Spring
有几种配置方式?答: 这里有三种重要的方法给Spring
容器提供配置元数据。
XML
配置文件。Java
的配置。Spring
配置文件包含了哪些信息?答: Spring
配置文件是个**XML
**** 文件**,这个文件包含了类信息、如何配置它们以及类之间的依赖关系。
Spring
基于xml
注入Bean
的几种方式?Set
方法注入;index
设置参数的位置;②通过type
设置参数类型;答: 当定义一个在Spring
里,我们还能给这个Bean
声明一个作用域。它可以通过 Bean
定义中的 scope
属性来定义。如,当Spring
要在需要的时候每次生产一个新的Bean
实例,那么该Bean
的scope
属性被指定为prototype
。另一方面,如果一个Bean
每次使用的时候必须返回同一个实例,这个Bean
的scope
属性必须设为singleton
。
Spring
支持的几种Bean
的作用域?singleton
: Bean
在每个Spring IOC
容器中只有一个实例。prototype
: 一个Bean
的定义可以有多个实例。request
: 每次http
请求都会创建一个Bean
,该作用域仅在基于 Web
的Spring ApplicationContext
情形下有效。session
: 在一个HTTP Session
中,一个Bean
定义对应一个实例。该作用域仅在基于 web
的Spring ApplicationContext
情形下有效。global-session
: 在一个全局的HTTP Session
中,一个Bean
定义对应一个实例。该作用域仅在基于 web
的Spring ApplicationContext
情形下有效。缺省的
Spring Bean
的作用域是Singleton
。使用prototype
作用域需要慎重的思考,因为频繁创建和销毁Bean
会带来很大的性能开销。
Spring
框架中的单例Bean
是线程安全的吗?答: 不是,Spring
框架中的单例Bean
不是线程安全的。
Spring 中的Bean
默认是单例模式,但是Spring
框架并没有对单例 Bean
进行多线程的封装处理。实际上大部分时候 Spring Bean
无状态的(比如 dao
类),所有某种程度上来说 Bean
也是安全的,但如果 Bean
有状态的话(比如 view model
对象),那就要开发者自己去保证线程安全了,最简单的就是改变 Bean
的作用域,把“singleton
”变更为“prototype
”,这样请求 Bean
相当于 new Bean()
了,所以就可以保证线程安全了。
答: 在一般情况下,只有无状态的 Bean
才可以在多线程环境下共享,在Spring
中,绝大部分Bean
都可以声明为作用域,因为 Spring
对一些 Bean
中非线程安全状态采用 ThreadLocal
进行处理,解决线程安全问题。ThreadLocal
做了哪些工作:
ThreadLocal
和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。同步机制采用了 “时间换空间” 的方式,仅提供一份变量,不同的线程在访问前需要获取锁,没获得锁的线程则需要排队。ThreadLocal
采用了 “空间换时间” 的方式。ThreadLocal
会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal
提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal
。Spring
框架中Bean
的生命周期?答:Bean
在Spring
容器中从创建到销毁经历了若干阶段,每一阶段都可以针对Spring
如何管理Bean
进行个性化定制。
Bean
进行实例化;Bean
的引用注入到 Bean
对应的属性中;Bean
实现了BeanNameAware
接口,Spring将Bean
的ID传递给 setBean-Name()
方法;Bean
实现了BeanFactoryAware
接口,Spring将调用 setBeanFactory()
方法,将BeanFactory
容器实例传入;Bean
实现了ApplicationContextAware
接口,Spring将调用setApplicationContext()
方法,将Bean
所在的应用上下文的引用传入进来;Bean
实现了BeanPostProcessor
接口,Spring将调用它们的postProcessBeforeInitialization()
方法;Bean
实现了InitializingBean
接口,Spring将调用它们的after-PropertiesSet()
方法。类似地,如果Bean
使用initmethod
声明了初始化方法,该方法也会被调用;Bean
已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁;Bean
实现了DisposableBean
接口,Spring将调用它的destroy()
接口方法。同样,如果Bean
使用 destroy-method
声明了销毁方法,该方法也会被调用。Bean
生命周期方法? 你能重载它们吗?答:
Bean
生命周期方法,第一个是 setup()
,它是在容器 加载 Bean
的时候被调用。第二个方法是 teardown()
它是在容器卸载类的时候被调用。Bean
标签有两个重要的属性(init-method
和destroy-method
)。用它们你可以自己定制初始化和注销方法。它们也有相应的注解(@PostConstruct和@PreDestroy)。Spring
的内部Bean
?什么是Spring inner Beans
?答: 在Spring
框架中,当一个 Bean
仅被用作另一个 Bean
的属性时,它能被声明为一个内部Bean
。内部Bean
可以用setter
注入“属性”和构造方法注入“构造参数”的方式来实现,内部Bean
通常是匿名的,它们的Scope
一般是prototype
。
Spring
中如何注入一个Java
集合?答:
List
: 类型用于注入一列值,允许有相同的值。Set
: 类型用于注入一组值,不允许有相同的值。Map
: 类型用于注入一组键值对,键和值都可以为任意类型。Props
: 类型用于注入一组键值对,键和值都只能为 String
类型。Bean
装配?答: 装配,或Bean
装配是指在Spring 容器中把 Bean
组装到一起,前提是容器需要知道 Bean
的依赖关系,如何通过依赖注入来把它们装配到一起。
Bean
的自动装配答: 在Spring
框架中,在配置文件中设定 Bean
的依赖关系是一个很好的机制,Spring
容器能够自动装配相互合作的Bean
,这意味着容器不需要配置,能通过Bean
工厂自动处理Bean
之间的协作。这意味着Spring
可以通过向BeanFactory
中注入的方式自动搞定 Bean
之间的依赖关系。自动装配可以设置在每个Bean
上,也可以设定在特定的Bean
上。
Spring
自动装配 Bean
有哪些方式?答: 在Spring
中,对象无需自己查找或创建与其关联的其他对象,由容器负责把需要相互协作的对象引用赋予各个对象,使用 Autowire
来配置自动装载模式。
在Spring
框架xml
配置中共有5种自动装配:
no
:默认的方式是不进行自动装配的,通过手工设置ref
属性来进行装配Bean
。byName
: 通过 Bean
的名称进行自动装配,如果一个Bean
的 property
与另一Bean
的name
相同,就进行自动装配。byType
: 通过参数的数据类型进行自动装配。constructor
: 利用构造函数进行装配,并且构造函数的参数通过byType
进行装配。autodetect
: 自动探测,如果有构造方法,通过 construct
的方式自动装配,否则使用byType
的方式自动装配。@Autowired
注解自动装配的过程是怎样的?答: 使用@Autowired
注解来自动装配指定的Bean
。在使用@Autowired
注解之前需要在 Spring
配置文件进行配置,
。
在启动Spring IoC
时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor
后置处理器,当容器扫描到@Autowied
、@Resource
或@Inject
时,就会在IoC
容器自动查找需要的Bean
,并装配给该对象的属性。
在使用@Autowired
时:
Bean
;Bean
装配给@Autowired
指定的数据;@Autowired
会根据名称来查找;required=false
。