Spring之IOC篇

Julywhj 2013-01-05

Spring是Rod Johnson提出的

Spring之所以与struts,Hibernate等单层框架不同,是因为Spring致力于提供一个统一的、高效的方式构造整个应用,并且可以将单层框架以最佳的组合揉合在一起建立一个连贯的体系。可以说Spring是一个提供了更完善开发环境的一个框架,可以为POJO(Plain Old Java Object)对象提供企业级的服务。Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架

Spring框架的优点:

1)Spring是分层结构,你可以选择使用你需要的层而不用管不需要的部分

2)Spring是POJO编程,POJO编程使得可持续构建和可测试能力提高

3)依赖注入和IoC使得JDBC操作简单化

4)Spring是开源的免费的

        5)Spring使得对象集中简单化

Spring之IOC篇:

  1、如何使用IOC来创建Bean?

1)配置Bean(定义bean):

在SpringBeanDefinition文件中配置Bean的相关信息:

id(名字)

class:要配实现类

属性:对象类型的属性

例:

<beanid="userDao"class="">

</bean>

<beanid="userService"class="...UserServiceImp">

    </bean>

 2)ApplicationContext是Spring的核心接口.

如何引用配置文件:ApplicationContextac=

newClassPathXmlApplicationContext("base.xml");

如果是多个配置文件,可以这样写:

ApplicationContextac=

 new ClassPathXmlApplicationContext(new String[]{"base.xml","order.xml",.....});

读取配置文件中的内容:    Book book =(Book)ac.getBean("book1");

  DI(Dependency Injection--依赖注入)

什么是依赖?对象A调用对象B,则A依赖于B

什么是依赖注入?将对象A所依赖的对象B通过setter方式注入

其实DI是IoC的别名,实现依赖注入的容器就是IoC

2、属性的注入方式:

有两种,我们需要掌握的是set方式的注入

1)setter方式属性设置器【掌握】

形式——<propertyname="属性名"value="值">

注意:用“value=xxx”只限于基本类型的属性——

    String、int等

   2)构造器方式    【了解】

Spring调用合适的构造器来创建实例

<constructor-argvalue="2"/>能智能判断,有几个就调用几个参数的构造器

优先处理字符串

<constructor-argtype="int"index="0"value="2"/>

<constructor-argtype="java.lang.String"index="1"value="book3"/>

3、属性的数据类型

1)基本类型

int,string,class等等

2)集合类型:List,Set,Map

<list>

<value>1234</value>(list中有几个值就写几个value)

</list>

<util:listname="versionlist">

里面放value的值

</util:list>(这个要写在bean的外面,用ref="versionlist"的方式注入)

3)对象属性--关联属性(最重要的)

案例:BookService--BookDAO

写法:

<beanid="bookDao"......./>

<propertyname="bookDao"ref="bookDao">

<refbean=""/>的作用就是引用一个以定义好的bean

关联属性注入的几种写法

i、<propertyname=""ref=""/>

ii、<propertyname="">

<refbean="全局的bean--即从所有的文件中找bean"/>

</property>

    <ref local="本文件的bean" />

4、依赖检查(Dependecy check):

问题:如何确保UserService中的userDao

被注入了呢?

有两种方式:

I.在Bean定义文件中指定(xml方式):

<beanid=""class=""dependecy-check="objects"/>

dependecy-check的取值:

i.noneii.simple基本类型(只对基本类型进行检查)

iii.objects只对所有的对象类型进行检查

iv.all对所有的属性进行检查

II.@Required注解方式

在需要检查的属性上加上注解

注意两点:i.在set方法上面加注解

ii.在bean定义文件中其中这个注解,让注解生效

<context:annotation-config/>

两种方式的对比:检查的范围不同

dependecy-check对整个Bean文件进行查找

      @Required针对某个属性

5、自动注入(Autowire--自动装配)

有两种方式:

i.xml方式<bean....byType"/>

byName:按照属性名,到Bean定义文件中查找相应的对象

byType:按照属性的类型进行查找,只能有且仅有一个匹配的bean(推荐使用)

ii.@Autowired

在需要检查的属性上加上注解

注意两点:i.在set方法上面加注解

ii.在bean定义文件中其中这个注解,让注解生效

<context:annotation-config/>

@Autowired使用的是byType方式,

默认是Required的,如不需要则@Autowired(required=false)

@Resource(name="bookDao")

    即可用ByName的方式

6、工厂方法分为三类:

1,静态工厂方法

<beanid="book1"class="myspring.bean.Book"/>这是一种构造器方式

例如:

要实现UserServiceservice=ServiceFactory.getUserService()

方法:如下——

<beanid="userService"class="工厂类"

factory-method="静态方法名"/>

2,实例工厂方法

例:

  Connection connection = dataSource.getConnection();

  工厂Bean  如dataSource

<beanid="myDataSource"class="org.apache.commons.dbcp.BasicDataSource">

<propertyname="driverClassName"value="com.mysql.jdbc.Driver"/>

<propertyname="url"value="jdbc:mysql://localhost:3306/hibernate"/>

<propertyname="username"value="root"/>

<propertyname="password"value=""/>

</bean>

<beanid="myConnection"factory-bean="myDataSource"

factory-method="getConnection">

3,工厂bean(自己创建的)【掌握】

概念:FactoryBean是负责创建Bean的Bean,

  该Bean必须实现Spring的FactoryBean接口

 FactoryBean(Spring定义的接口):

getObject:创建并返回Bean实例

getObjectType:返回Bean的Class。

例:书打折

<beanid="discountbook1"

class="myspring.bean.DiscountBookFactoryBean">

<propertyname="bookId"value="1"/>

<propertyname="bookName"value="book1"/>

<propertyname="bookPrice"value="30"/>

<propertyname="discount"value="0.5"></property>

</bean>

7、Bean的作用域——Scope【特别注意】

学习要点:定义Bean后,在获取这个Bean时,每次获取的Bean是否相同。

i.singleton:单例每次获取同一个bean,生命周期和Spring一样

ii.prototype:原型(非单例)每次getBean()时获取的不是同一个

<beanid=""class=""scope="prototype"/>

对象的分类

1、数据对象:Book、User

2、行为对象:UserService、ServiceFactory提供具体功能的对象

业务对象(实现订单管理等业务功能)、

服务对象(提供某些特定服务-事务、

数据库服务如Hibernate的Session)

在bean文件中定义的一般为行为对象,没有状态的,(即没有数据的)

结论:Bean文件中定义的Bean一般为单例模式,所以Spring默认把bean当成singleton的

如何判断该用哪种scope?

标准:看该Bean有无状态。有状态——Prototype

8、Bean的生命周期

1)创建:调用构造器生成实例

2)Setter:给属性赋值

3)init-method:初始化回调方法(会被

Spring自动调用)

4)准备就绪:在getBean()之前

5)destroy-method:销毁前回调方法(善后工作)

6)JVM回收bean

例MyFileLogger

打开文件——initmethod中处理

关闭文件——destroymethod中处理

两种指定方式

1)xml方式:

<beanid=""class=""init-method=""

destroy-method=""/>

2)注解——@PostConstruct(“创建后”)、

@PreDestroy(“销毁前”)

注意:用“<context:annotation-config/>”

启用注解

9、模板装配

先定义一个模板Bean,然后再定义bean时

引用这个模板Bean,这样就可以使用模板

Bean中的配置信息;也可以在bean中覆盖

  掉模板Bean中的属性等配置信息。

  <bean id="" parent="模板Bean">  </>

  子Bean不能从模板bean继承哪些信息:

主要为autowire、dependency-check、

lazy-init、scope。

 10、BeanPostProcessor —— 后置处理器

   在Bean创建并初始化完毕之后,

对Bean进行进一步的初始化处理。

特点:它可对所有的Bean进行处理。

例子:目录的预先创建

自己定义的后置处理器要实现implementsBeanPostProcessor

在Spring中有一些预定义的后置处理器:

RequiedAnnotationBeanPostProcessor

AutowiredAnnotationBeanPostProcessor

CommonAnnotationBeanPostProcessor当这个后置处理器起作用时,

自定义的后置处理器就会失效

后置处理器执行顺序让后置处理器实现Ordered接口,PriorityOrdered优先级接口

里面包含setOrder/getOrder

从0开始,数字越小就越靠前。

扩展机制增加功能

先写一个后置处理器实现这俩BeanPostProcessor,PriorityOrdered

BeanPostProcessor是为了实现初始化之前和初始化之后的工作,记住都需要修改返回值

,默认的是返回null,都要改成返回对象bean,分别在里面进行相应的操作

PriorityOrdered是修改后置处理器的优先级,order属性的值越小,优先级越高

 

11、如何使用属性文件:

引入属性文件:

<context:property-placeholderlocation="sys-conf.properties"/>

使用属性文件:形如“${propName}”

<propertyname="filePath"value="${fileLogger.path}"/>

12、处理多语言的步骤

i、创建语言文件文件名的前缀自己决定,但是都得一样,最后再来一个无后缀的文件

message_en.properties

message_zh.properties

message.properties

ii、实现MessageSourceAware

iii、调用MessageSource的getMessage()

Stringmsg=messageSource.getMessage("fileLogger.prompt",

newObject[]{logInfo,newDate()},

Locale.CHINA);

iv、在Bean定义文件中定义MessageSource:

名字固定为"messageSource"

<beanid="messageSource"class="org.springframework.context.support.ResourceBundleMessageSource">

<propertyname="basename"value="message"/>

</bean>

13、组件扫描——ComponentScanning

自动扫描

扫描用@Component所标记的类

@Component("userDao")

classUserDAO{

}

Spring会“自动加入”——

<beanid="userDao"class=""/>

组件component:对象

<context:component-scanbase-package=""/>

用来启动component组件,扫描base-package包及其子包的所有类

@Component

@Service:如UserService

@Repository:代表数据库UserDAO

    @Controller:代表前端

Spring之web篇

1.在web.xml中添加Spring的Listener,以启动Spring。

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>classpath:base.xml</param-value>

    </context-param>

    <listener>

<listener-class>

org.springframework.web.context.ContextLoaderListener

</listener-class>

    </listener>

  2.在service方法中使用:

WebApplicationContextac=WebApplicationContextUtils.

getRequiredWebApplicationContext(getServletContext());

ac.getBean("");

接下去就根据具体的业务逻辑来码代码

相关推荐