Java拾遗之Spring Ioc

Java拾遗之Spring Ioc

标签:Spring Ioc


写在前面

框架已经使用了快半年了,一直都打算写点东西巩固巩固,但一直都没动笔的冲动。
于某日心血来着,开写。
顺序是按照本人学习的顺序来写的,主要是想通过写的过程将所有知识点再串一下,回归一下。(另:也为后人学习提供更多的教程选择)

Spring

我是打算的先从框架开始写,前面的知识,例如Java Web的Servlet、JSP部分,我的博客上已经有了,我记得是我已经将我之前学习的笔记贴在了博客中,请自行参考。
当然后面我可能会重新将这些东西整理一下,当然也只是个可能,具体视我心情而定。
至于更前面的Java语法部分,以及HTML、CSS、JavaScript等Web基础部分,这个本人暂时不打算写。相关教程请自行百度。。。

Spring框架简介

Spring是什么

介绍某个东西之前,当然先介绍它是什么。先允许我引入一段较为官方的解释:

Spring是一个开源的轻量级的应用开发框架,其目的是用于简化企业级应用程序开发,减少侵入;
Spring提供的IOC和AOP应用,可以将组件的耦合度降至最低,即解耦,便于系统日后的维护和升级;
Spring为系统提供了一个整体的解决方案,开发者可以利用它本身提供的功能外,也可以与第三方框架和技术整合应用,可以自由选择采用哪种技术进行开发。

换成人话就是:Spring是一个框架,用它可以减少代码量,降低组件之前的耦合度。

为什么要用Spring

我们都知道,在如今各类面向对象的设计思想下,各类软件的业务编写都是通过一个一个对象来实现的,而Spring的作用就是用来管理所用到的这些对象,例如创建对象维护对象之间的关系

容器与Bean的管理

Spring容器简介

Spring其实是通过容器的方式来管理对象的,在Spring的容器中,任何Java类和Java Bean都被当做Bean来处理,而容器正是通过管理这些bean来起到管理对象的左右的。
Spring的容器实现的Ioc(控制反转)和AOP(面向切面编程)机制,这些机制可以简化Bean对象的创建和Bean对象之间的解耦。
Spring的容器有BeanFactory和ApplicationContext两种类型

Spring容器的实例化

ApplicationContext是继承自BeanFactory接口的,拥有更多的企业方法,所以推荐使用该类型,实例化方法如下:

// 加载文件系统中的配置文件
String conf = "C:\applicationContext.xml";
ApplicationContext ac = new FileSystemXmlApplicationContext(conf);

// 加载工程下classpath的配置文件
String conf = "applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);

Spring容器的使用

从本质上讲,BeanFactory和ApplicationContext仅仅只是一个维护Bean定义以及相互依赖关系的高级工厂接口。通过BeanFactory和ApplicationContext我们可以访问bean定义。
首先在容器配置文件applicationContext.xml中添加Bean定义

<bean id="标识符" class="bean类型" />

然后在创建BeanFactory和ApplicationContext容器对象后,调用getBean()方法获取Bean的实例即可

bean的实例化

通过构造器来实例化

<bean id="obj1" class="java.util.GregorianCalendar" />

<bean name="obj2" class="java.util.GregorianCalendar" />

id或name属性用于指定Bean名称, 用于从Spring中查找这个Bean对象
class用于指定Bean类型, 会自动调用无参数构造器创建对象

使用静态工厂实例化

<bean id="calendarObj2" class="java.util.Calendar" factory-method="getInstance"/>

id属性用于指定Bean名称;
class属性用于指定工厂类型;
factory-method属性用于指定工厂中创建Bean对象的方法,必须用static修饰的方法。

使用实例工厂方法实例化

<bean id="calendarObj3" class="java.util.GregorianCalendar"/>

<bean id="dateObj" factory-bean="calendarObj3" factory-method="getTime"/>

id用于指定Bean名称;
factory-bean属性用于指定工厂Bean对象;
factory-method属性用于指定工厂中创建Bean对象的方法。

Bean的命名

bean的名称

在Spring容器中,每个Bean都需要有名字(即标识符),该名字可以用 <bean>元素的id或name属性指定
id属性比name严格,要求具有唯一性,不允许用“/”等特殊字符

bean的别名

为已定义好的Bean,再增加另外一个名字引用,可以使用<alias>指定

<alias name="fromName" alias="toName"/>

Bean的作用域

Spring容器在实例化Bean时,可以创建以下作用域的Bean对象

作用域 描述
singleton 在每个SpringIoC容器中一个bean定义对应一个对象实例,默认项
prototype 一个bean定义对应多个对象实例
request 在一次HTTP请求中,一个bean定义对应一个实例,仅限于Web环境
session 在一个HTTP Session中,一个bean定义对应一个实例,仅限于Web环境
global Session 在一个全局的HTTP Session中,一个bean定义对应一个实例;仅在基于portlet的Web应用中才有意义,Portlet规范定义了全局Session的概念

上面的Bean作用域,可以通过<bean>定义的scope属性指定

Bean的生命周期回调

  • 指定初始化回调方法
<bean id="exampleBean" class="com.foo.ExampleBean " init-method= " init" >
</bean>
  • 指定销毁回调方法,仅适用于singleton模式的bean
<bean id="exampleBean" class="com.foo.ExampleBean" destroy-method= "destroy" >
</bean>

提示:指定销毁回调方法,仅适用于singleton模式的bean

  • 在顶级的 <beans/>元素中的default-init-method属性,可以为容器所有指定初始化回调方法
<beans default-init-method ="init">
    <bean id="exampleBean" class="com.foo.ExampleBean “/>
 </beans>
  • 在顶级的<beans/>元素中的default-destroy-method属性,可以为容器所有<bean>指定销毁回调方法
<beans default-destroy-method =“destroy">
    <bean id="exampleBean" class="com.foo.ExampleBean “/>
 </beans>

Bean延迟实例化

在ApplicationContext实现的默认行为就是在启动时将所有singleton bean提前进行实例化
如果不想让一个singleton bean在ApplicationContext初始化时被提前实例化,可以使用<bean>元素的lazy-init=”true”属性改变
一个延迟初始化bean将在第一次被用到时实例化

<bean id="exampleBean" lazy-init="true" class="com.foo.ExampleBean "/>

在顶级的<beans/>元素中的default-lazy-init属性,可以为容器所有<bean>指定延迟实例化特性

指定bean依赖关系

当一个bean对另一个bean存在依赖关系时,可以利用<bean>元素的depends-on属性指定

<bean id="beanOne" class="ExampleBean" depends-on="manager"/> 
<bean id="manager" class="ManagerBean" />

当一个bean对多个bean存在依赖关系时,depends-on属性可以指定多个bean名,用逗号隔开

<bean id="beanOne" class="ExampleBean" depends-on="manager1, manager2"/>

容器的Ioc应用

Ioc的概念

IoC全称是Inversion of Control,被译为控制反转;
IoC是指程序中对象的获取方式发生反转,由最初的new方式创建,转变为由第三方框架创建、注入。第三方框架一般是通过配置方式指定注入哪一个具体实现,从而降低了对象之间的耦合度
IOC按实现方法不同,可以分为依赖注入DI依赖查找两种
Spring容器是采用DI方式实现了IOC控制,IOC是Spring框架的基础和核心;

DI全称是Dependency Injection ,被译为依赖注入;
DI的基本原理就是将一起工作具有关系的对象,通过构造方法参数或方法参数传入建立关联,因此容器的工作就是创建bean时注入那些依赖关系。
IOC是一种思想,而DI是实现IOC的主要技术途径
DI主要有两种注入方式,即Setter注入构造器注入

Setter注入

通过调用无参构造器或无参static工厂方法实例化bean之后,调用该bean的setter方法,即可实现setter方式的注入。

public class JDBCDataSource {
    private  String driver;
    public void setDriver(String driver)    { 
        try{//注册数据库驱动
    Class.forName(driver);
    this.driver = driver;
        }catch(Exception e){
    throw new RuntimeException(e);
        }
    }
     //其他代码… …
}

在容器xml配置中,配置注入参数。

<bean id="dataSource" class="org.tarena.dao.JDBCDataSource">
    <property name="driver" value="oracle.jdbc.OracleDriver"/>
    <property name="url" value="jdbc:oracle:thin:@localhost:1521:XE"/>
     <property name="user" value="openlab"/>
     <property name="pwd" value="open123"/>
</bean>

构造器注入

基于构造器的注入是通过调用带参数的构造器来实现的, 容器在bean被实例化的时候,根据参数类型执行相应的构造器。

public class OracleUserDAO implements UserDAO{
    private JDBCDataSource dataSource;
    public OracleUserDAO(JDBCDataSource dataSource) {
        this.dataSource = dataSource;
    }
     //其他代码… …
}

按构造参数索引指定注入

<bean id="dataSource" class="org.tarena.dao.JDBCDataSource">
    <property name="driver" value="oracle.jdbc.OracleDriver"/>
    <property name="url" value="jdbc:oracle:thin:@localhost:1521:XE"/>
    <property name="user" value="openlab"/>
    <property name="pwd" value="open123"/>
</bean>
<bean id="userDAO" class="org.tarena.dao.OracleUserDAO">
    <constructor-arg index="0" ref="dataSource"/>
</bean>

自动装配

Spring IoC容器可以自动装配(autowire)相互协作bean之间的关联关系,autowire可以针对单个bean进行设置,autowire的方便之处在于减少xml的注入配置
在xml配置文件中,可以在<bean/>元素中使用autowire属性指定自动装配规则,一共有五种类型值

属性值 描述
no 禁用自动装配,默认值
byName 根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配
byType 如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配
constructor 与byType的方式类似,不同之处在于它应用于构造器参数
autodetect 通过bean类来决定是使用constructor还是byType方式进行自动装配。如果发现默认的构造器,那么将使用byType方式

配置实例

<bean id="userDAO" class="org.tarena.dao.OracleUserDAO">
    <constructor-arg index="0" ref="dataSource"/>
</bean>
<bean id="userService" class="org.tarena.service.UserService" autowire="byType"/>

上述配置,在UserService中如果存在接收UserDao类型的方法Setter方法,Spring就可以自动将userDAO对象注入进去

猜你喜欢

转载自blog.csdn.net/jsong1025/article/details/50373648