Spring(之一)--基本用法

Spring是为企业应用的开发提供轻量级解决方法。包括:基于依赖注入的核心机制、基于AOP的声明式事务管理、与多种持久层技术的整合,以及优秀的Web MVC框架等。Spring贯穿表现层、业务层、持久层。
Spring优点:

  • 低侵入式设计代码污染低。
  • 独立于各种应用服务器。
  • Spring的IOC容器降低了业务对象替换的复杂性,提高组件之间的解耦。
  • Spring的AOP支持允许将一些通用任务如安全、事物、日志等进行集中式处理,从而提供更好的复用。
  • Spring的ORM和DAO提供了与第三方持久层框架的良好整合,简化了底层的数据库访问。
  • Spring的高度开放性,并不强调应用完全依赖与Spring,开发者可自由选择所需部分。
    下图是Spring框架的组成结构图
    Spring框架的组成结构图

Spring管理Bean

使用Spring管理Bean,Spring把容器中的一切对象统称Bean。Spring对Bean没有任何要求,只要是一个java类就可以。所以一切对象都是Bean。Spring使用配置文件管理。

伪代码片段

//在xml中的配置
<bean id ="" class ="">
    <property name ="" value ="" ref ="">
//在Spring底层的实现
    String id = "";
    Class clazz = class.forName(classStr);
    Object obj = clazz.newInstance();
    container.put(id, obj);

    String name = "";
    String ref ="";
    String classStr = "";
    String setterName = "set"+name.subString(0,1).toUpperCase()+name.subString(1);
    Object param = container.get(ref);
    Method setter = clazz.getMethod(setterName, param.getClass());
    setter.invoke(obj, param);

在Spring配置文件中配置Bean时,class属性的值必须是Bean实现类的完整类名,不能是接口,不能是抽象类,否则Spring无法使用发射创建类的实例。bean元素驱动Spring调用构造器,它的作用是默认驱动Spring在底层调用无参构造器创造对象,property驱动Spring执行setter方法,name属性值决定执行哪个setter方法(所以name的值跟java代码中的属性值相对应),而value或ref决定传入的参数值。这两步是先后执行的,中间几乎没有任何间隔。

在程序中使用Spring容器

ApplicationContext是Spring容器最常用接口,该接口有两个常用实现类:

  • ClassPathXmlApplicationContext:从类加载路径下搜索配置文件,并根据配置文件来创建Spring容器。
  • FileSystemXmlApplicationContext:从文件系统的相对路径或绝对路径下去搜索配置文件,并根据配置文件来创建Spring容器。
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
Object obj = ctx.getBean("",xx.class);//使得程序不在使用new 调用构造器创建java对象,所有的java对象由Spring负责创建

Spring核心机制:依赖注入

也叫控制反转(IOC)或者依赖注入(DI),使用Spring框架之后,调用者获取被依赖对象的方式由原来的主动获取,变成了被动接受。所以,叫控制反转。从容器的角度讲,Spring容器负责将被依赖对象赋值给调用者的成员变量,相当于为调用者注入它依赖的实例。
使用Spring框架之后的主要改变

  • 程序无需使用new创建对象。
  • 当要调用被依赖对象的方法,调用者无需主动获取被依赖对象,只要等待Spring
    容器注入即可。

使用Spring IoC容器的三个基本要点

  • 应用程序的各组件面向接口编程。
  • 应用程度的各组件不再由程序主动创建
  • Spring采用配置文件或注解来管理Bean的实现类、依赖关系,Spring容器则根据配置文件或注解,利用反射来创建实例,并为之注入依赖关系。

依赖注入通常两种
- 设值注入:使用成员变量的setter注入被依赖的对象
- 构造注入:使用构造器注入被依赖的对象。constructor-arg来代表构造参数
区别:设值注入先是通过无参构造器创建一个Bean实例,然后调用对应的setter方法注入依赖关系;构造注入是直接调用有参构造,当Bean实例创建完成后,已经完成了依赖注入。最后,建议采用以设值注入为主,构造注入为辅的策略。对于依赖关系无需变化的注入,尽量采用构造注入。

使用Spring容器

Spring有两个和新接口:

  • BeanFactory
  • ApplicationContext

ApplicationContext是BeanFactory的子接口。Spring是生成Bean的工厂,并管理bean。
**区别**BeanFactory不会预初始化容器中的Bean,ApplicationContext会自动预初始化容器中的singleton Bean,也可以手动取消预初始化。所以,系统前期创建ApplicationContext时开销比较大,但一旦初始化完成,程序后面获取singleton Bean性能提升。一般推荐使用ApplicationContext。

ApplicationContext的事件机制

ApplicationContext的事件机制是观察者设计模式的实现,通过ApplicationEvent类和ApplicationListener类接口,可以实现ApplicationContext的事件处理。

  • ApplicationEvent 容器事件,必须由ApplicationContext发布
  • ApplicationListener 监听器,可由容器中的任何监听器Bean担任
    这里写图片描述
    事件机制主要有事件源、事件、事件监听器组成。ApplicationContex是事件源,且事件必须由java程序显式触发。

容器中Bean的作用域

当通过Spring创建一个Bean实例,不仅可以完成bean实例化而且可以为Bean指定作用域。有5个作用域:

  • singleton 单例模式,将在整个容器只生成一个Bean实例,容器负责维护Bean生命周期。一旦创建成功可以重复使用。
  • prototype 每次通过容器获取都会获得一个新的实例,一旦创建成功,容器将不再会负责其生命周期。创建销毁代价较大。
  • request 对于一次HTTP请求
  • session 一次HTTP会话
  • global session 只有在Web应用中此作用才有效

使用自动装配注入合作者Bean

Spring的自动装配可通过autowire属性指定,该属性只对配置文件中所有的bean起作用,该属性可接受的值:

  • byType:根据setter方法的形参进行自动装配
  • byName:根据setter方法名进行自动装配,如果找到多个这样的Bean就会抛出异常,如果没有找到,就什么也不会发生。
  • constructor:与byType类似,区别是用于自动匹配的构造器的参数。如果找不到这样的Bean会抛出一个异常。
  • autodetect:Spring容器根据Bean内部结构,自行决定使用constructor或byType策略。如果找不到一个默认的构造器函数,就会应用byType。

spring的Bean和JavaBean

Spring容器对Bean没有特殊要求,甚至不要求该bean像标准的JavaBean必须为每个属性提供相应的setter和getter方法。Spring中的Bean是Java实例、Java组件;而传统的JavaBean是作为DTO(数据传输对象),用来封装值对象,在各层之间传递数据。
Spring中的Bean应满足几个原则

  • 尽量为每个Bean实现类提供无参的构造器
  • 接受构造注入的Bean,则应提供对应的带参数的构造函数
  • 接受值注入的Bean,则应提供对应的setter方法,并不需要提供相应的getter方法

传统的JavaBean和Spring中的Bean存在的区别:

  • 用处不同:传统的JavaBean更多是作为值对象传递参数;Spring的Bean用处无处不包,任何应用组件都被称为Bean。
  • 写法不同:传统的JavaBean作为值对象要求每个属性都提供getter和setter方法;但Spring的Bean只需为接受设置注入的属性提供setter方法即可。
  • 生命周期不同:传统的JavaBean作为值对象传递,不接受任何容器管理其生命周期;Spring中的Bean由Spring管理其生命周期行为。

创建Bean的方式

  • 调用构造器创建Bean
  • 调用静态工厂方法创建Bean
  • 调用实例工厂方法创建Bean

调用静态工厂方法创建Bean

  • class属性也必须指定,但此时class属性并不是指定Bean实例的实现类,而是静态工厂类。Spring通过该属性知道哪个工厂类来创建Bean实例。
  • factory-method属性指定静态工厂方法返回一个Bean实例。
    当静态工厂方法创建了Bean实例后,Spring依然可以管理该Bean实例的依赖关系,包括为其注入所需的bean、管理器生命周期。

调用实例工厂方法创建Bean

实例工厂方法和静态工厂方法不同:配置静态工厂方法使用class指定静态工厂类,而配置实例工厂方法则使用factory-bean指定工厂实例。使用实例工厂方法时,配置bean实例的bean元素无需class属性,因为Spring容器不在直接实例化该Bean,Spring容器仅仅调用实例工厂的方法,工厂方法负责创建Bean实例。

  • factory-bean
  • factory-method

区别

调用静态工厂方法创建Bean与调用实例工厂方法创建Bean,相同之处
- 都需要使用factory-method
- 工厂方法如果需要使用参数,都是用constructor-arg元素指定参数值
- 普通的设置注入,都是用property确定参数值
不同之处

  • 配置实例工厂方法创建Bean,必须将实例工厂配置成Bean实例;而配置静态工厂方法创建Bean则无需配置工厂Bean。
  • 配置实例工厂方法创建Bean,必须使用factory-bean属性确定工厂Bean;而配置静态工厂方法创建Bean,则使用class元素确定静态工厂类。

    抽象Bean与子Bean

    将多个bean元素配置中的相同信息提取出来,集中成配置模板,这个bean并不是真正的bean,并且需要增加abstract=true,这就是抽象bean。抽象Bean不能被实例化,Spring容器不会创建抽象Bean实例,t它的价值在于被继承,所以可以不指定class属性。
    子Bean可以通过parent属性指定其父的Bean,当子Bean所指的配置信息与父Bean不一致时将会覆盖父的bean。

Bean继承与Java继承的区别

前者是一般到特殊的细化,后者是实例与实例之间参数值的延续。前者是类与类之间的关系,后者是对象与对象的关系。区别

  • Spring中的子Bean不可作为父Bean使用,不具备多态性;Java中的有多态性
  • Spring中的主要表现为参数值得延续;而java中的主要表现为方法、属性的延续。
  • Spring中的子Bean与父Bean可以是不同类型,而java中可以保证子类是父类的特殊类型。

容器中的工厂Bean

这种工厂Bean必须实现FactoryBean接口,把工厂Bean部署在容器中之后,如果通过getBean获取它,容器返回的不是factoryBean实现类而是返回factoryBean的产品。
实现factoryBean接口的价值:Spring容器并不是简单的返回该实例而是返回该Bean实例的getObject方法的返回值,而该方法由开发者负责实现。

容器中Bean的生命周期

Spring可以管理singleton作用域的Bean的生命周期,可以精确的知道这个Bean何时被创建、何时被初始化完成、容器何时准备销毁该Bean实例。
对于Prototype作用域的Spring仅负责创建,当容器创建了Bean之后,完全交给客户端管理,容器不在跟踪其生命周期。
对于singleton作用域的,Spring可以管理实例化结束之后和销毁之前的行为,主要有两个时机:

  • 注入依赖关系之后
    提供两种方式执行特定行为:使用init-method属性;实现InitializingBean接口
  • 即将销毁之前
    提供两种方式执行特定行为:使用destroy-method属性;实现DisposableBean接口

这里写图片描述

总结

Spring的本质就是通过XML配置来执行Java代码,因此几乎可以把所有的Java代码放到Spring配置文件中管理。

  • 调用构造器创建对象,用bean元素
  • 调用setter方法,用property元素
  • 调用getter方法,用PropertyPathFactoryBean或 util:property-path元素
  • 调用普通方法,用MethodInvokeingFactoryBean工厂bean
  • 获取Field的值,用FieldRetrievingFactoryBean或util:constant元素

Spring IoC容器的作用:将原来的java代码管理的耦合关系,提取到xml中进行管理,从而降低了各组件之间的耦合,提高了系统的可维护性。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值