您的位置:首页 > 编程语言 > Java开发

1、Spring3核心技术-IoC(一)

2013-10-16 21:24 309 查看
简介:SpringIoc主要决议的问题就是Bean 的实例化和依赖问题,我们可以将Bean的实例化工作交给Spring进行管理这样我们就不需要在到处new对象了,这只是一个小方面重要的是Spring帮助我们解决了Bean依赖的问题,也就是耦合问题,淡然我们希望我们的程序各个模块甚至是功能在代码上耦合度越低越好,Spring帮我们做了很大的优化。此文环境为Spring3.2。

Spring对于Context和Bean的配置可以使用不同方式,这里采用xml加annotation的形式进行后面会总结说一下spring的Context和Bean的配置方式:

1:简单的使用Spring创建的Bean

2:Spring3 Ioc容器

3:Spring中Bean的配置和属性

4:Spring Ioc和J2EE CDI

1:简单的使用Spring创建的Bean

1.1:引入Spring3相关jar文件【这个测试中并不会用到所有jar这里简单起见引入所有jar,后面会简要介绍些部分jar提供的功能】



1.2:在源码包下添加Spring的初始化文件beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 
<context:component-scan base-package="org.fp.smark.spring3"></context:component-scan>//Spring会在这里定位你的Bean
</beans>

这里beans.xml作为初始文件,文件名是可以更改的,也可以有多个同类型的xml后面会介绍。

1.3:测试Spring IoC容器

MainService.java :我们自己的Bean,

package org.fp.smark.spring3;

import org.springframework.stereotype.Service;

@Service("mainService")
public class MainService {

public void hello(){
System.out.println("hello m Service");
}
}

IOCTest.java :测试类
package org.fp.smark.spring3;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class IOCTest {

ApplicationContext context  = new ClassPathXmlApplicationContext("beans.xml");

@Test
public void test1(){
MainService service = context.getBean("mainService",MainService.class);
service.hello();
}
}

context:ApplicationContext的实例,你在beans.xml中做的所有配置都会在Spring的容器中进行配置和映射,这里也包括通过注解进行的配置,ApplicationContext是你接入Spring容器的入口;当然Spring的设计肯定不会简单到值通过这一个类来作为初始化入口,后面会介绍Spring在配置文件相关的内容和初始化Spring环境的一些内容。

2:Spring3 Ioc容器

你可以将Spring Ioc容器想象成是我们应用程序的一个大的上下文环境,我们所有通过Spring配置的Bean都可以再这里找到,我们只是写好我们的Bean关于bean的初始化、依赖关系、作用域等都是通过Spring配置(这里特指通过Ioc技术配置)。下面介绍一下Spring3
Ioc容器:Ioc容器相关的两个主要包org.springframework.context、org.springframework.beans;BeanFactory提供了高级的配置机制来管理所要类型的Bean,同时Spring提供了两个比较好用的的接口ApplicationContext和WebApplicationContext,看名字就可以知道这两个类的区别,这两类都是BeanFactory的子类,他们主要提供了与Spring其他组件和功能的交互,包括Spring
AOP 、资源处理(会在后面说明)等。下面通图2-1来描述下Ioc容器管理相关的类和接口:



图 2-1

说明:当然Spring的组织不会如此的简单,这两主要是为了说明问题没有分析所有“Context”类的关系,在E1中我们的测试类中我看使用了ClassPathXmlApplicationContext类来初始化Spring,它通过加载在classpath下定义的配置文件来初始容器,FileSystemApplicationContext支持通过文件系统来加载配置文件。WebApplicationContext是和Web相关的初始化入口。下面是ApplicationContext的一个大致继承关系图2-2:



图 2-2

Spring的核心架构相当简单 图2-3摘自Spring3.2文档:你可以抽象的理解就是使用Spring来组织自己的各种类(事实上Spring做的远远不止这些)。



图 2-3

3:Spring中Bean的配置和属性:

(下面主要以Annotation配置来说明,Annotation的配置相对写起程序来说比较简单但Xml方式提供了更好的扩展性这个在实际引用中要分析来使用,个人认为一些主要的配置也就是一些入口级的bean在xml中配置比如数据源JMX接入等,细节东西在annotation中配置比较好用比如应用逻辑中自实现的一些bean)。

3.1:Bean相关的一些概念

Scope:

Spring定义了5中Scope类型如图3-1



图 3-1

其中request、session、global session只有在web环境下是有效的,这里先接受前两个,和web相关的定义在SpringMVC中介绍;

singleton:也就是单例模式的实现,在所用使用singleton Scope定义的bean来说都是是同一个对象;
prototype:也就是原型模式,每一个对使用prototype Scope定义的Bean的引用的Bean所得到的都是一个新的Bean;
e3.2:本小节将以annotation方式介绍一下常用的配置
使用Spring配置的所有Bean我们都可以成为Component,Spring中@Component注解也就是这么做的,你可以将自己的Bean注解上@Component然后交给Spring管理,Spring从2.5开始将组件注解有细分了几类
@Repository
@Service、
@Controller从名字中我们可以看出这是实际上是与MVC的对应,使用上述三个注解的Bean都可以使用@Component来注解,但是上述三个是针对各层次进行优化了的,而且在我们的应用程序中也能更清晰的区分不同业务层的Bean。@Repository从Spring2.0中就引入但还不是对应DAO层的注解,@Service注解是对应我们应用的服务级别类,@Controller注解我们会在SpringMVC中介绍也就是控制层注解。


3.2.1:使用@Component注解示例:类关系如图3-2(beans.xml配置文件使用e1.2即可)



图 3-2

IOCTest.java 测试类

package org.fp.smark.spring3;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class IOCTest {

ApplicationContext context  = new ClassPathXmlApplicationContext("beans.xml");

@Test
public void test1(){
MainService service = context.getBean("mainService",MainService.class);
service.hello();
}
}

测试类通过ClassPathXMLApplication加载配置文件,并调用MainService的hello方法;

MainService.java

package org.fp.smark.spring3;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;

@Service("mainService")  //指定MainService的名字context可以通过这个名字找到这个对象
public class MainService {

@Resource	//使用@Resource注解标明这是一个被注入的资源
private BasicDao basicDao;

public void hello(){
System.out.println("hello m Service");
basicDao.saveEntity();
}
}


BasicDao.java

package org.fp.smark.spring3;
import org.springframework.stereotype.Component;

@Component("basicDao") //通过@Component进行注解,并指定名字
public class BasicDao {

public void saveEntity(){
System.out.println("entity saved");
}
}


Console输出:



说明:通过这三个类我们就可以简单的了解Spring Ioc了,下面接收一下使用到的两个注解;

@Component:这个注解在前面已经简单的提过了,你可以通过@Component("componectName")来指定这个Bean的名字,这个名字是在使用@Resource定位资源是用到的;当然你也可以不指定,默认是类名第一个字母小写也就是basicDao。
@Resource:你可以将在类使用的其他对象通过@Resource进行注解这样Spring会自动帮你创建这个对象,你直接使用就可以了,在上例中我们看到@Resource并没有传入参数,默认它是根据定义的对象名也就是basicDao去查找,当指定了名字后他会去按名字查找,@Resource并不仅仅代表容器内资源,你也可以通过@Resource获取JNDI资源等这里先不介绍。
@Scope:你可以在类上使用@Scope(BeanDefinition.SCOPE_SINGLETON)注解来使用singleton Scope.

3.2.2:beans.xml配置文件解析

我们以1.2中的beans.xml为例来看,这个文件简单的只有一行

<context:component-scan base-package="org.fp.smark.spring3"></context:component-scan>

来配置,实时上这行配置做了很多工作,从名字我们可以看出其作用就是扫描配置的组件也就是我们自定义的Bean,上面的一行配置隐含的也实现了
<context:component-scan>
,其对应的是配置了 
AutowiredAnnotationBeanPostProcessor和 CommonAnnotationBeanPostProcessor来处理注解,
这是我们可以使用注解来进行Spring配置的原因,我们使用注解进行了配置后Spring就能管理我们的各种Bean了。以也可以像下面这样指定扫描包的过滤规则:
[code] <context:component-scan base-package="org.example">
<context:include-filter type="regex" expression=".*Stub.*Repository"/>
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Repository"/>
</context:component-scan>

4、Spring IOC和J2EE CDI

先分析一下概念Inversion of Control(控制反转IOC)、Dependence Injection(依赖注入DI)虽然两个概念不同(有些人认为其实是同一个概念)但是其目的是一致的,个人认为IOC主要是用户设计程序时的理解重要的是人理解程序设计中的概念(可能有些模糊),DI是注重藐视程序中类的关系,Spring中的概念是IOC而J2EE中则使用的DI的概念,J2EE从6开始引入DI概念主要是更加JSR
330实现(Dependency Injection for Java 1.0

),J2EE7中同样是1.0版本的JSR330实现,Spring中也支持JSR330你可以在Spring中使用@Inject和@Named等注解(个人并不推荐这样做)如果你有需求可以从Spring文档中核心技术The Ioc Container中找到相关的说明,个人推荐如果是使用Spring使用Spring自身提供的注解更方便灵活肯定功能也更强大。DI概念引入到J2EE中你可能在其他应用中使用到这个技术来提供类似Spring IOC的效果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: