Spring framework内容整理
来源:互联网 发布:艾媒咨询数据 编辑:程序博客网 时间:2024/05/21 14:26
1、Spring framework简介
Spring 是一个轻量级的控制反转(IoC)和面向切面编程(AOP)的容器框架。Spring具有非侵入性,通过IoC促进了松耦合。
2、IoC:控制反转(Inversion of control)解说
在传统程序开发过程中,如果在一个对象要使用另一个对象,就必须得到它(自己new一个,或者从JNDI中查询一个),使用完之后还要将对象销毁(比如数据库连接对象Connection等),这样对象始终会和其他的接口或类耦合起来。
而使用Spring,所有的类都会在Spring容器中登记,告诉Spring自己是什么,需要什么,然后Spring会在系统运行到适当的时候把要的东西主动给你,同时也把你交给其他需要你的对象。所有类的创建、销毁都由Spring来控制,控制对象生存周期的不再是引用它的对象,而是Spring。IoC是Spring的核心,控制权的转移即反转。
3、DI:依赖注入(Dependency Injection)介绍
IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点通过DI实现。
比如对象A需要操作数据库,以前我们是在A中自己编写代码来获得一个Connection对象,而使用Spring,只需告诉我们需要一个Connection,在系统运行时,Spring会在适当的时候制造一个Connection,注入到A中,这样就完成了对各个对象之间的关系控制。
A需要依赖Connection才能正常运行,而Connection由Spring注入到A中,即为依赖注入。4、实例说明
HelloWorldImpl.java
package com.iholtek;import java.util.Date;public class HelloWorldImpl { public String sayHello( String message ){ return new Date() + " hello," + message; }}
HelloWorldTest.java
package com.iholtek;import org.apache.log4j.Logger;import org.apache.log4j.PropertyConfigurator;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class HelloWorldTest { static final Logger log = Logger.getLogger( HelloWorldTest.class); ApplicationContext appContext; public void loadXML() { // 載入XML appContext = new ClassPathXmlApplicationContext( "springtest.xml" ); } public void testHello() { // 利用Application Context 的getBean建立Instance. HelloWorldImpl helloworld =(HelloWorldImpl) appContext.getBean( "HelloWorld" ); String s = helloworld.sayHello( "Tom"); System.out.println( s ); } public static void main( String [] args ){ HelloWorldTest test = new HelloWorldTest(); test.loadXML(); test.testHello(); }}
springtest.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="HelloWorld" class="com.iholtek.HelloWorldImpl" > </bean></beans>
分析:在上面的例子中,实作一个类,并且在springtest.xml配置文件中定义,之后就可以通过在测试类中调用ClassPathXmlApplicationContext方法载入XML配置文件,找到并装载完成ApplicationContext对象的实例化工作,并调用ApplicationContext的getBean方法建立类实例。(与构造方法来构建相比,可以发现Spring能在不修改代码的情况下抽换实作的类)
不过HelloWorldImpl类没有接口,不利于抽象,所以定义一个HelloWorld接口,由HelloWorldImpl实现。这样在配置文件中抽换不同的实作,在测试类中调用getBean后强制类型转换为接口类型,不需更改代码,这样的抽象化才有较大意义。5、处理bean的依赖关系步骤:
(1)根据定义bean的配置文件创建并初始化BeanFactory实例(大部分Spring用户使用支持XML格式配置文件的BeanFactory或ApplicationContext实现)。
(2)每个bean的依赖将以属性、constructor参数、或静态工厂方法参数的形式出现。当这些bean被实际创建时,这些依赖也将提供给该bean。
(3)每个属性或constructor参数既可以是一个实际的值,也可以是对该容器中另一个bean的引用。
(4)每个指定的属性或constructor参数值必须能够被转换成属性或参数所需类型。默认情况下,Spring能够以String类型提供值转换成各种内置类型,如int、long、String、boolean等。
【Spring会在容器被创建时验证容器中每个bean的配置,包括验证bean所引用的属性是否指向一个有效的bean(即在容器中被定义)。但是,在bean被实际创建之前,bean的属性并不会被设置,伴随着bean被实际创建,作为该bean的依赖bean以及依赖bean的依赖bean(类推)也将被创建和分配。对于singleton类型和被设置为提前实例化的bean(如ApplicationContext中的singleton bean),bean实例将与容器同时创建。】
6、循环依赖
一个类A,需要通过constructor注入类B,类B又需要通过constructor注入类A。如果配置的bean被互相注入的话,那么Spring IoC容器将在运行时检测出循环引用,并抛出异常。
解决方法一,修改源码为setter注入;方法二,完全放弃使用constructor注入,只使用setter注入。
7、延迟初始化bean
在默认情况下,ApplicationContext实现中的bean采用启动时提前实例化的singleton模式,在实际需要前创建bean会带来时间和内存开销,不过ApplicationContext被加载的时候可以尽早发现一些配置问题(也可以根据需要采用延迟实例化替代默认singleton模式)。
延迟加载(延迟实例化,延迟初始化):在对象第一次被使用时实例化,而不是在启动时。
在XML配置文件中,延迟初始化通过<bean/>元素中的lazy-init属性控制。
<bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"> <!-- various properties here... --></bean> <bean name="not.lazy" class="com.foo.AnotherBean"> <!-- various properties here... --></bean>
在容器层次中通过在<beans/>元素上使用'default-lazy-init'属性来控制延迟初始化也是可能的。如下面的配置:
<beans default-lazy-init="true"> <!-- no beans will be eagerly pre-instantiated... --></beans>
【 如果一个bean被设置为延迟初始化,而另一个非延迟初始化的singleton bean依赖于它,那么当ApplicationContext提前实例化singleton bean时,必须确保所有上述singleton 依赖的bean也被预先初始化,包括设置为延迟实例化的bean】
8、引用其他bean——ref标签
第一种:<ref bean=”someBean”/>
最常见,通过ref的bean属性指定目标bean,通过该标签可以引用同一容器或父容器内的任何bean(无论是否在同一配置文件),ref内bean属性的值既可以是指定的bean的id、也可以是name。
第二种:<ref local=”someBean”/>
通过ref的local属性指定目标bean,local属性值必须是目标bean的id值。如果在同一配置文件中没有找到引用的bean,XML解析器会抛出一个例外。如果目标bean在同一文件,则local方式是最好的选择(可以尽早发现错误)。
第三种:
<!-- in the parent context --><bean id="accountService" class="com.foo.SimpleAccountService"> <!-- insert dependencies as required as here --></bean>
<!-- in the child (descendant) context --><bean id="accountService" <!--和父context中bean的id一样 class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target"> <ref parent="accountService"/> <-- notice how we refer to the parent bean </property> <!-- insert other configuration and dependencies as required as here --></bean>
通过ref的parent属性来引用当前容器的父容器中的bean。Parent属性值既可以是目标bean的id、也可以是name。而且目标bean必须在当前容器的父容器中。主要用途是为了用某个与父容器中的bean同名的代理来包装父容器中的一个bean。
9、内部bean
所谓内部bean(inner bean)是指在一个bean的<property/>或<constructor-arg/>元素中使用<bean/>元素定义的bean。内部bean中的singleton标记和id或name属性将被忽略。
<bean id="outer" class="..."> <property name="target"> <bean class="com.mycompany.Person"> <!-- this is the inner bean --> <property name="name" value="Fiona Apple"/>。。。 </bean> </property></bean>
【 内部bean总是匿名的,而且总是prototype模式的;将内部bean注入的包含该内部bean之外的bean是不可能的】
10、Collection类型的配置
通过<list/>,<set/>, <map/>, <props/>元素可以定义和设置于Java Collection类型对于的List,Set,Map,Properties的值。
<bean id="moreComplexObject" class="example.ComplexObject"> <property name="adminEmails"> <props> <prop key="administrator">administrator@somecompany.org</prop> <prop key="support">support@somecompany.org</prop> <prop key="development">development@somecompany.org</prop> </props> </property> <property name="someList"> <list> <value>a list element followed by a reference</value> <ref bean="myDataSource" /> </list> </property> <property name="someMap"> <map> <entry> <key> <value>yup an entry</value> </key> <value>just some string</value> </entry> </map> </property> <property name="someSet"> <set> <value>just some string</value> <ref bean="myDataSource" /> </set> </property></bean>
11、null标签
<null/>用于处理null值。因为Spring会吧属性的空参数当做空字符串处理,所以
<bean class="ExampleBean"> <property name="email"><value></value></property></bean>
等同于exampleBean.setEmail(“”)。所以用<null/>取代。
12、自动装配(autowire)
Spring IoC容器可以自动装配相互合作bean之间的关联关系。当Spring在读取bean的配置文件时,读到某个bean的autowire属性时会去找class指定的类,然后根据类中的属性或方法在的参数的参数类型<autowire=bytype>(或名字autowire=byname)查找相应的类实例化,然后完成依赖注入(要用相应set方法)。Autowire的方便之处在于减少或消除属性或constructor参数的设置,简化配置文件。
Autowire一个有5种类型:
(1)no:不用自动装配,必须通过ref指定,这是默认设置。显示指定合作者是配置更灵活、清晰,相对于大的部署配置,推荐。
(2)byName:根据属性名自动装配,将检查容器并跟名字查找与属性完全一致的bean自动装配。
(3)byType:如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配。如果存在多个该类型的bean,会抛出异常,并指出不能用byType进行自动装配。如果没有找到相匹配的bean,则什么事都不发生,属性也不会被设置,如果不希望这样,可以通过设置dependency-check=”objects”让spring抛出异常。
(4)constructor:与byType类似,不过这里用于constructor参数。如果在容器中没有找到与constructor参数类型一致的bean,会抛出异常。
(5)autodetect:通过bean的自省机制(introspection)决定是使用constructor还是byType。如果发现默认的constructor,则使用byType。
13、定制bean特性
Spring提供了几个接口用来改变容器中bean的行为,包括InitializingBean,DisposableBean 。
(1)InitializingBean
实现org.springframework.beans.factory.InitializingBean接口允许容器在设置好bean的所有必要属性后,执行初始化事宜。该接口仅提供一个方法:
void afterPropertiesSet() throws Exception;
通常要避免使用InitializingBean,因为会将代码和Spring耦合。可以在bean定义中指定一个普通的初始化方法,即在XML配置文件通过指定init-method属性来完成。
(2)DisposableBean
实现org.springframework.beans.factory.DisposableBean接口允许在容器销毁该bean的时候获得一次callback。只提供一个方法:
void destroy() throws Exception;
同样会耦合,可以定义一个普通析构方法,在配置文件通过destroy-method指定。
(3)BeanFactoryAware
对于实现了spring的org.springframework.beans.factory.BeanFactoryAware接口的类,只要实现setBeanFactory方法就可以以编码的方式获取创建它们的BeanFactory。当类被BeanFactory创建后,会拥有一个指向创建它的BeanFactory的引用,能够取得BeanFactory所管理的其他bean。不过会使代码与Spring耦合,而且违反Ioc原则(所需的其他bean应该作为属性提供),所以要避免使用。
public interface BeanFactoryAware { void setBeanFactory(BeanFactory beanFactory) throws BeansException;}
(4)BeanNameAware
让Bean获取自己在BeanFactory配置中的名字(根据情况是id 或 name)
实现org.springframework.beans.factory.BeanNameAware接口的唯一方法setBeanName()
public class LogginBean implements BeanNameAware{private String beanName=null;public void setBeanName(String beanName){this.beanName=beanName;}}该方法由Spring自动调用,在Spring自身完成Bean配置后,且在调用任何Bean生命周期回调(初始化或销毁)方法之前就调用该方法。所以,在程序中使用BeanFactory.getBean(StringbeanName)之前,Bean的名字就已经设定好了,不用但是没被初始化。
不过由于耦合问题,最好让Bean自己实现某个方法,如setName(),之后使用依赖注入给每个Bean注入一个名字。
- Spring framework内容整理
- spring-framework目录内容概述
- Spring框架内容整理(一):IOC
- Spring框架内容整理(二):DI
- Spring框架内容整理(三):AOP
- Spring框架内容整理(四):Spring事务处理
- Spring framework
- Spring Framework
- Spring Framework
- Spring Framework
- Spring Framework
- Spring Framework
- Spring Framework
- Spring framework
- Spring Framework
- spring framework
- Spring framework
- Spring Framework
- 年度网络购物十大被投诉网站淘宝、当当位居前二正文
- Java虚拟机类加载顺序研究
- Struts 2工作流程
- Java read and write csv file(注意事项)
- curl 命令使用
- Spring framework内容整理
- 从零开始学C++之模板(四):用模板实现单例模式(线程安全)、模板方式实现动态创建对象
- Smarty模板原理
- ping命令流程详解
- ExtJS(二)--AJAX基础
- varchar和Nvarchar区别
- (译)如何使用box2d来做碰撞检测(且仅用来做碰撞检测)
- 外部用户连接到oracle
- 忘记root时密码时修改root密码