:: 首页 ::  :: 联系 :: 聚合  :: 管理

Spring的核心是个lightweitht container,他是实现IOC容器、非侵入性(No Intrusive)的框架,并提供AOP概念的实现方式,提供Persistencetransaction的支持,提供MVC Web框架的实现,并对一些常用的企业服务API提供一致的模型封装,是一个全方位的Application Framework

一、Spring部分术语介绍

No Intrusive应用程序几乎感觉不到框架的存在,减低应用程序在框架移植时的负担,进一步增加应用程序组件的Reusability

控制反转(IoC):依赖关系的转移。程序不应依赖实现,而是依赖于接口。

即如果A依赖B,则B拥有控制权。依赖关系的反转即是控制关系的反转,将控制权由实现的一方转移至抽象的一方,藉由让抽象方拥有控制权,可以获得组件的壳重用性。

在例子中,整个控制权从实际的FloppyWriter转移到抽象的IDeviceWriter接口上m而让Business依赖于IDeviceWriter接口,而FloppyWriterUsbDiskWriter也依赖于IDeviceWriter接口。

依赖注入(Dependency Injection):IoC模式是一个高层的模式概念,实现IoC有两种方式:Dependency InjectionService LocatorSpring采用的是DI

保留抽象接口,让组件依赖于抽象接口,当组件要与其他实际的对象发生依赖关系时,通过抽象接口来注入依赖的实际对象。

依赖注入的三种实现方式:Interface InjectionSetter InjectionConstructor Injection

二、第一个Spring程序。

载入配置文件:

1Resource rs = new ClassPathResource("SpringDemo\\applicationContext.xml");
2BeanFactory factory = new XmlBeanFactory(rs);

ClassPathResource:从系统的类路径中加载,在上述的代码中,目录的层次结构如下图所示:


FileSystemResource:从文件系统加载,比如说自己指定配置文件的全路径 

InputStreamResource:从输入流中加载 

ServletContextResource:从Servlet 上下文环境中加载 

UrlResource:从指定的Url加载 

一、Bean、消息、事件

1. BeanFactoryApplicationContext

BeanFactory负责读取Bean定义文件,管理对象的加载、生成,维护Bean对象与Bean对象之间的依赖关系,负责Bean的生命周期。

ApplicationContext具备如BeanFactory基本的容器管理功能之外,还提供一个应用程序所需的更完整的框架功能,如取得资源文件的更方便的方法,提供文字消息解析的方法,支持国际化消息,事件的发布、处理与传播等。

建议用ApplicationContext替代BeanFactory。在实现ApplicationContext的类中,最常用的是以下三个:

org.springframework.context.support.FileSystemXmlApplicationContext:可指定XML定义文件的相对路径或者绝对路径来读取定义文件。

org.springframework.context.support.ClassPathXmlApplicationContext:从Classpath设定路径中来读取XML定义文件。

2. 使用Constructor Injection

即使使用Constructor Injection,也建议定义一个无参构造方法,以让Spring可以有使用无参构造方法来生成对象的弹性。

Bean定义文件中,必须指定构造方法上参数的顺序,如下

<bean id="hello" class="SpringDemo.HelloBean">
    
<constructor-arg index="0" value="codingliyi" />
    
<constructor-arg index="1" value="Hello" />
</bean>

建议使用Setter构造方法。有时需要隐藏某属性的Setter方法时(如使该属性变为只读或私有),可使用Constructor Injection

3. 属性绑定

如某个Bean实例只被某个属性参考一次,之那么可以在属性定义时使用Bean标签,并仅需指定其class属性即可。

1<property name="date">
2    <bean class="java.util.Date"/>
3</property>

Spring也支持隐式的自动绑定。

1<bean id="helloBean" class="SpringDemo.HelloBean" autowire="byType|byName|constructor|autodetect" dependency-check="simple|objects|all|none"/>

若使用byType无法完成绑定,则抛出异常;

若使用byName无法完成绑定,则对应得Setter仅维持未绑定状态;

若使用constructorSpring容器会试图比较对应容器中的Bean实例类型,及相关构造方法上的参数类型;

若使用autodetectSpring首先尝试constructor,不行的话再尝试byType

dependency-check指定依赖检查的方式,默认为none。如进行依赖检查时发现有未完成的伊拉关系,则执行时会跑出异常。

4. 集合类属性的注入。

<property name="list|set">
    
<list|set>
        
<value>hello</value>
        
<ref bean="helloBean"/>
    
</list|set>
</property>
<property name="map">
    
<map>
        
<entry key="name" value="codingliyi" />
        
<entry key="person">
            
<ref bean="codingliyi"/>
        
</entry>
    
</map>
</property>
<property name="properties">
    
<props>
        
<prop key="name">codingliyi</prop>
    
</props>
</property>

 

5. Bean的生命周期

使用BeanFactory来生成及管理Bean实例时:

Bean的建立:读取Bean定义文件,生成Bean的实例。

属性注入:执行相关Bean属性的依赖注入。

BeanNameAwaresetBeanName():

Bean实现了BeanNameAware接口,则执行。

BeanFactoryAwaresetBeanFactory():

Bean实现了BeanFactoryAware接口,则执行。

BeanPostProcessorsprocessBeforeInitialization():

如任何BeanPostProcessors实例与Bean实例关联,则执行。

InitializingBeanafterPropertiesSet()

Bean实现了InitializingBean接口,则执行。

Bean定义文件中定义的init-method

如定义了init-method,则执行设定的方法名称。

BeanPostProcessorsprocessAfterInitialization():

如任何BeanPostProcessors实例与Bean实例关联,则执行。

DisposableBeandestory()

Bean实现了DisposableBean接口,则执行。

Bean定义文件中定义的destory-method

如定义了destory-method,则执行设定的方法名称。

若使用ApplicationContext,在执行setBeanFactory()后,若bean有实现ApplicationContextAware接口,则执行setApplicationContext(),接着再继续执行之后的流程。

6. Bean高级管理

Aware接口

有时为了善用Spring所提供的一些功能,必须让Bean知道Spring容器管理的一些细节,或者让它知道BeanFactory,ApplicationContext的存在。

Spring中提供了一些Aware接口。如BeanNameAwareBeanFactoryAwareApplicationContextAware

Bean实现了上述接口后,在依赖关系设定完成之后,初始化方法之前,Spring容器会注入对应的实例。

(在暑期实习中做的那个Flex项目,需要在Action层使用ApplicationContext得到服务层组件。当时使用的是直接在代码中用new创建。其实现在看来可以实现ApplicationContextAware接口)

BeanPostProcessor接口

1public interface BeanPostProcessor {    
2    public Object postProcessAfterInitialization(Object bean, String name)throws BeansException;
3
4    public Object postProcessBeforeInitialization(Object bean, String name)throws BeansException;
5    }

6}

    例如将注入的String改为大写,代码如下:

 1public Object postProcessBeforeInitialization(Object bean, String name)
 2        throws BeansException {
 3    Field[] fields = bean.getClass().getDeclaredFields();
 4    for(Field field : fields){
 5        if(field.getType().equals(String.class)){
 6            try {
 7                String original = (String)field.get(bean);
 8                field.set(bean, original.toUpperCase());
 9            }
 catch (IllegalArgumentException e) {
10                e.printStackTrace();
11            }
 catch (IllegalAccessException e) {
12                e.printStackTrace();
13            }

14        }

15    }

16    return bean;
17}


7. 
资源、消息、事件

ApplicationContext除了具备如BeanFactory基本的容器管理功能之外,并支持更多应用框架的特性,像是资源的取得、消息解析、事件的处理与传播。

资源的取得:ApplicationContext继承了ResourceLoader接口,可使用getResource()方法并指定资源文件的URL来取得一个实现Resource接口的实例。

Resource resource = context.getResource("classpath:admin.properties");

也可以指定其他标准的URL,如file:或http:等。

在Spring应用程序执行期间,ApplicationContext本身就会发布一连串的事件,而所有发布的时间都是抽象类ApplicationEvent的子类。

ApplicationContext会在ApplicationEvent发布时通知实现了ApplicationListener的Bean类实例。

如果打算发布事件通知ApplicationListener的实例,则可使用ApplicationContext的publishEvent()方法。



只有注册用户登录后才能发表评论。


网站导航: