`

Spring(一)

阅读更多
具体内容
3.1、Spring的作用
之前的开发模式:Struts + Hibernate,由Hibernate完成具体的数据库操作,但是开发者在开发中就必须不断的处理一些与具体业务无关的操作,例如:Session的打开与关闭、事务处理等,那么实际上这些与业务无关的操作又决定了程序的最终运行效果,如果不关闭数据库,则程序到一定程度就无法再继续使用了。
业务逻辑层由Spring去做,整合前台和后台数据库间的互操作。
要创建一个类的实例化对象有多少种方法?
  • 直接使用new关键字,最直接的做法。
  • 通过Class创建
  • 对象克隆
  • 对象引用传递。
使用new直接实例化对象则会加深耦合度,如果使用工厂解耦合的话,如果一个项目中的接口过多,则会造成工厂过大,维护并不方便,而且修改子类的时候也需要修改工厂。
设计原则:
• 高层模块不应该依赖于底层模块,二者都应该依赖于抽象
• 抽象不应该依赖于细节,细节应该依赖于抽象
• 依赖于抽象的具体方式
1、任何变量都不应该持有一个指向具体类的指针或者引用
2、任何类都不应该从具体的类派生
3、任何方法都不应该覆写它的任何基类中的已经实现了的方法

Spring的组成模块是非常多的,而且本身在设计的时候就相当于把大部分的开源项目完全的整合在了一起。
Spring管理ORM是整个Spring的一个重点,它会负责事务的处理、数据库的打开与关闭。
Spring本身完全是针对于接口的编程,如果要想使用Spring接口是必不可少的。
使用MyEclipse进行Spring的开发。


表示定义Spring的核心配置文件,文件名称一般都默认为:applicationContext.xml,此名称可以修改,但是不建议这样使用。
例如:定义以下的一个接口:
package org.lxh.simple;
public interface Hello {
public String sayHello() ;
}
有接口之后应该定义子类,子类要实现此接口
例如:定义接口的子类 —— 得到大写的内容
package org.lxh.simple.impl;
import org.lxh.simple.Hello;
public class HelloUpperImpl implements Hello {
public String sayHello() {
  return "HELLO WORLD!!!";
}
}
例如:定义接口的子类 —— 得到小写的内容
package org.lxh.simple.impl;
import org.lxh.simple.Hello;
public class HelloLowerImpl implements Hello {
public String sayHello() {
  return "hello world!!!";
}
}
如果按照之前的做法,此时应该定义的是一个工厂类,但是现在有了Spring之后不用再单独定义工厂类了,所有的内容通过Spring的配置文件 —— applicationContext.xml进行统一的管理。
<bean id="hello"       注册一个bean的名称
  class="org.lxh.simple.Hello"    此bean对应的包.类名称
  abstract="true"></bean>     此bean是一个抽象的是不能被实例化的
<bean id="hellolower"    注册一个bean的名称
  class="org.lxh.simple.impl.HelloLowerImpl"
  parent="hello">    此bean的父类或父接口是那一个bean(要求必须在文件中存在)
</bean>
<bean id="helloupper"
  class="org.lxh.simple.impl.HelloUpperImpl"
  parent="hello">
</bean>
以上的程序代码通过配置文件完成之后,以后在程序中就不再需要new关键字实例化,而是通过Spring自动进行实例化操作。
范例:测试程序 —— Test.java
• 测试的过程中所有的bean的实例都要求从Spring的配置文件中找到。
package org.lxh.simple.test;
import org.lxh.simple.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
  ApplicationContext ctx = null ;
  // 表示找到配置文件
  ctx = new ClassPathXmlApplicationContext("applicationContext.xml") ;
  // 从配置文件之中取得Bean的实例
  Hello hello = (Hello)ctx.getBean("hellolower") ;
  System.out.println(hello.sayHello());
}
}
以上的代码已经可以得到一个子类的实例,与之前的工厂设计相比,有如下的好处:
  • 程序不用再处理工厂的实例化
  • 程序以接口为标准
  • 程序中通过key,可以找到一个具体的value。
如果要修改使用的子类,直接修改applicationContext.xml文件即可,而不用再去修改任何的程序代码,便于程序的变更。
实际上Spring就相当于是一个大的工厂。
那么除此之外Spring还有那些好处呢?直接修改实现类:将实现类变为一个:
package org.lxh.simple.impl;
import org.lxh.simple.Hello;
public class HelloImpl implements Hello {
private String info ;
public String sayHello() {
  return this.getInfo();
}
public String getInfo() {
  return info;
}
public void setInfo(String info) {
  this.info = info;
}
}
此实现类中存在了一个info属性,也同时存在了setter及getter方法,此时info的内容可以直接通过配置文件设置到类之中。
<bean id="helloimpl"
  class="org.lxh.simple.impl.HelloImpl"
  parent="hello">
  <property name="info">
   <value>helloworld!!!</value>
  </property>
</bean>
在配置文件之中,<bean>的节点下增加了<property>节点,表示要为bean中的属性赋值,内容为helloworld!!,以后如果在程序中直接使用了helloimpl实例化Hello接口的话,会自动把内容设置到HelloImpl类中的info属性之中。
public class Test {
public static void main(String[] args) {
  ApplicationContext ctx = null ;
  // 表示找到配置文件
  ctx = new ClassPathXmlApplicationContext("applicationContext.xml") ;
  // 从配置文件之中取得Bean的实例
  Hello hello = (Hello)ctx.getBean("helloimpl") ;
  System.out.println(hello.sayHello());
}
}
从以上的代码中可以发现,Spring完全是由配置文件决定效果的,所有的关系、属性的内容都可以通过Spring的配置文件指定,实际上这就是Spring中对于Ioc(控制反转)的支持
3.2、IOC的作用
之前的代码是使用了依赖注入的方式把内容设置到Bean类之中,实际上在Spring中依赖注入可以有多种形式,例如,可以在构造方法上传递所需要的内容。
例如:现在有如下的一个类
public class Person {
private String name ;
private int age ;
public Person(String name, int age) {
  this.name = name;
  this.age = age;
}
public int getAge() {
  return age;
}
public void setAge(int age) {
  this.age = age;
}
public String getName() {
  return name;
}
public void setName(String name) {
  this.name = name;
}
public String toString(){
  return "姓名:" + this.name + ";年龄:" + this.age ;
}
}
在此类中没有无参构造方法,之后可以直接通过applicationContext进行配置。
applicationContext.xml:
<bean id="per1" class="org.lxh.ioc.demo01.Person">
  <constructor-arg index="0">    构造方法的参数,index表示参数的位置
   <value>zhangsan</value>     表示参数的内容
  </constructor-arg>               第二个参数
  <constructor-arg index="1">
   <value>30</value>            是一个数字,所以直接写上数字
  </constructor-arg>
</bean>
验证:
public class Test {
public static void main(String[] args) {
  ApplicationContext ctx = null ;
  // 表示找到配置文件
  ctx = new ClassPathXmlApplicationContext("applicationContext.xml") ;
  // 从配置文件之中取得Bean的实例
  System.out.println(ctx.getBean("per1"));
}
}
除了以上的注入方式外,还可以指定一个bean的实例注入进去。
例如:在配置文件之中声明一个java.util.Date的对象。
<bean id="date" class="java.util.Date"></bean>
之后声明一个包含了date属性的POJO类。
Person.java:
package org.lxh.ioc.demo02;
import java.util.Date;
public class Person {
private String name ;
private int age ;
private Date birthday ;
public Date getBirthday() {
  return birthday;
}
public void setBirthday(Date birthday) {
  this.birthday = birthday;
}
public Person(String name, int age) {
  this.name = name;
  this.age = age;
}
public int getAge() {
  return age;
}
public void setAge(int age) {
  this.age = age;
}
public String getName() {
  return name;
}
public void setName(String name) {
  this.name = name;
}
public String toString(){
  return "姓名:" + this.name + ";年龄:" + this.age + "生日:" + this.birthday ;
}}
把之前配置的date对象设置到Person类之中。
<bean id="per2" class="org.lxh.ioc.demo02.Person">
  <constructor-arg index="0">
   <value>zhangsan</value>
  </constructor-arg>
  <constructor-arg index="1">
   <value>30</value>
  </constructor-arg>
  <property name="birthday">
   <ref bean="date"></ref>     表示使用本配置文件之中配置好的date实例
  </property>
</bean>
测试:
public class Test {
public static void main(String[] args) {
  ApplicationContext ctx = null ;
  // 表示找到配置文件
  ctx = new ClassPathXmlApplicationContext("applicationContext.xml") ;
  // 从配置文件之中取得Bean的实例
  System.out.println(ctx.getBean("per2"));
}
}
那么,此时,实际上就可以利用此种概念,注入更加复杂的类型,例如:自定义两个类,之后在配置文件中建立关系。
例如:一个人有一本书
Person.java:
package org.lxh.ioc.demo03;
public class Person {
private String name ;
private int age ;
private Book book ;
public Book getBook() {
  return book;
}
public void setBook(Book book) {
  this.book = book;
}
public int getAge() {
  return age;
}
public void setAge(int age) {
  this.age = age;
}
public String getName() {
  return name;
}
public void setName(String name) {
  this.name = name;
}
public String toString(){
  return "姓名:" + this.name + ";年龄:" + this.age ;
}
}
Book.java:
package org.lxh.ioc.demo03;
public class Book {
private String title ;
private float price ;
public float getPrice() {
  return price;
}
public void setPrice(float price) {
  this.price = price;
}
public String getTitle() {
  return title;
}
public void setTitle(String title) {
  this.title = title;
}
}
在配置文件中配置出此种关系
<bean id="book3" class="org.lxh.ioc.demo03.Book">
  <property name="title">
   <value>JAVA</value>
  </property>
  <property name="price">
   <value>99.9</value>
  </property>
</bean>
<bean id="per3" class="org.lxh.ioc.demo03.Person">
  <property name="name">
   <value>zhangsan</value>
  </property>
  <property name="age">
   <value>30</value>
  </property>
  <property name="book">
   <ref bean="book3"></ref>
  </property>
</bean>
在此配置文件之中完全的将两个类的关系进行合理的配置,直接从配置文件之中就可以发现之间的联系。
public class Test {
public static void main(String[] args) {
  ApplicationContext ctx = null ;
  // 表示找到配置文件
  ctx = new ClassPathXmlApplicationContext("applicationContext.xml") ;
  // 从配置文件之中取得Bean的实例
  Person per = (Person)ctx.getBean("per3") ;
  System.out.println(per.getBook().getTitle());
}
}
在IOC中还有一种技术称为自动绑定,可以自动绑定所需要的类型的对象,有byType、byName方式。
1、 使用类型进行自动绑定
package org.lxh.ioc.demo04;
import java.util.Date;
public class Person {
private String name ;
private int age ;
private Date birthday ;
public Date getBirthday() {
  return birthday;
}
public void setBirthday(Date birthday) {
  this.birthday = birthday;
}
public int getAge() {
  return age;
}
public void setAge(int age) {
  this.age = age;
}
public String getName() {
  return name;
}
public void setName(String name) {
  this.name = name;
}
public String toString(){
  return "姓名:" + this.name + ";年龄:" + this.age + ";生日:" + this.birthday ;
}
}
将配置好的Date的实例通过类型自动设置进去
<bean id="per4" class="org.lxh.ioc.demo04.Person" autowire="byType">
  <property name="name">
   <value>zhangsan</value>
  </property>
  <property name="age">
   <value>30</value>
  </property>
</bean>
测试:
public class Test {
public static void main(String[] args) {
  ApplicationContext ctx = null ;
  // 表示找到配置文件
  ctx = new ClassPathXmlApplicationContext("applicationContext.xml") ;
  // 从配置文件之中取得Bean的实例
  System.out.println(ctx.getBean("per4"));
}
}
通过类型自动把内容设置进去了,自动注入。
2、 通过名称注入
<bean id="birthday" class="java.util.Date"></bean>
<bean id="per5" class="org.lxh.ioc.demo05.Person" autowire="byName">
  <property name="name">
   <value>zhangsan</value>
  </property>
  <property name="age">
   <value>30</value>
  </property>
</bean>
可以发现,在定义date类型的时候,名称与Person类中的Date属性名称一致,此时直接使用byName绑定。
以上的两种比较常用,如果需要的话,还可以直接在构造方法上进行自动的绑定操作。
例如:有如下的类
import java.util.Date;
public class Person {
private Date birthday ;
public Date getBirthday() {
  return birthday;
}
public Person(Date birthday) {
  super();
  this.birthday = birthday;
}
public void setBirthday(Date birthday) {
  this.birthday = birthday;
}
public String toString(){
  return "生日:" + this.birthday ;
}
}
在以上的类中,是通过构造方法进行内容的设置,配置如下:
<bean id="per6" class="org.lxh.ioc.demo06.Person"
  autowire="constructor">
</bean>
使用IOC可以注入更加复杂的内容,例如:对象数组、List、Set、Map类型的数据
1、 对于注入对象数组和List实际上配置文件没有太大的区别,是一样的,只是内部接收的方式不一样。
建立一个Person的POJO类,同时在建立一个书的类,一个人有多本书。此时注入的是一组对象,可以使用对象数组或是List进行接收。
Book.java:
public class Book {
private String title ;
private float price ;
public float getPrice() {
  return price;
}
public void setPrice(float price) {
  this.price = price;
}
public String getTitle() {
  return title;
}
public void setTitle(String title) {
  this.title = title;
}
}
建立Person的类,Person类中包含多个Book对象。
Person.java:
public class Person {
private String name ;
private int age ;
private Book[] books ;
public Book[] getBooks() {
  return books;
}
public void setBooks(Book[] books) {
  this.books = books;
}
public int getAge() {
  return age;
}
public void setAge(int age) {
  this.age = age;
}
public String getName() {
  return name;
}
public void setName(String name) {
  this.name = name;
}
public String toString(){
  return "姓名:" + this.name + ";年龄:" + this.age ;
}
}
Person类中存在了一个书的对象数组,此时,通过配置文件进行关系的配置。
<bean id="book1" class="org.lxh.ioc.demo07.Book">
  <property name="title">
   <value>JAVA</value>
  </property>
  <property name="price">
   <value>100</value>
  </property>
</bean>
<bean id="book2" class="org.lxh.ioc.demo07.Book">
  <property name="title">
   <value>Oracle</value>
  </property>
  <property name="price">
   <value>111</value>
  </property>
</bean>
<bean id="book3" class="org.lxh.ioc.demo07.Book">
  <property name="title">
   <value>JSP</value>
  </property>
  <property name="price">
   <value>122</value>
  </property>
</bean>
<bean id="per7" class="org.lxh.ioc.demo07.Person">
  <property name="name">
   <value>zhangsan</value>
  </property>
  <property name="age">
   <value>30</value>
  </property>
  <property name="books">
   <list>
    <ref bean="book1"/>
    <ref bean="book2"/>
    <ref bean="book3"/>
   </list>
  </property>
</bean>
测试:
public class Test {
public static void main(String[] args) {
  ApplicationContext ctx = null ;
  // 表示找到配置文件
  ctx = new ClassPathXmlApplicationContext("applicationContext.xml") ;
  // 从配置文件之中取得Bean的实例
  Person per = (Person)ctx.getBean("per7") ;
  System.out.println(per) ;
  Book b[] = per.getBooks() ;
  for(int i=0;i<b.length;i++){
   System.out.println("\t|- " + b[i].getTitle());
  }
}
}
此时,可以直接把类中的对象数组修改为List集合,两者的运行效果是完全一样的。
Person.java:
package org.lxh.ioc.demo08;
import java.util.List;
public class Person {
private String name ;
private int age ;
private List books ;
public List getBooks() {
  return books;
}
public void setBooks(List books) {
  this.books = books;
}
public int getAge() {
  return age;
}
public void setAge(int age) {
  this.age = age;
}
public String getName() {
  return name;
}
public void setName(String name) {
  this.name = name;
}
public String toString(){
  return "姓名:" + this.name + ";年龄:" + this.age ;
}
}
配置文件不需要做任何的修改,因为在配置的时候本身使用的就是<list>节点。测试:
public class Test {
public static void main(String[] args) {
  ApplicationContext ctx = null ;
  // 表示找到配置文件
  ctx = new ClassPathXmlApplicationContext("applicationContext.xml") ;
  // 从配置文件之中取得Bean的实例
  Person per = (Person)ctx.getBean("per8") ;
  System.out.println(per) ;
  Iterator iter = per.getBooks().iterator() ;
  while(iter.hasNext()){
   Book b = (Book)iter.next() ;
   System.out.println("\t|- " + b.getTitle());
  }
}
}
也可以直接使用Set节点进行注入。
  <property name="books">
   <set>
    <ref bean="book1"/>
    <ref bean="book2"/>
    <ref bean="book3"/>
   </set>
  </property>
还可以把内容作为Map注入进来。
package org.lxh.ioc.demo09;
import java.util.Map;
public class Person {
private String name ;
private int age ;
private Map books ;
public Map getBooks() {
  return books;
}
public void setBooks(Map books) {
  this.books = books;
}
public int getAge() {
  return age;
}
public void setAge(int age) {
  this.age = age;
}
public String getName() {
  return name;
}
public void setName(String name) {
  this.name = name;
}
public String toString(){
  return "姓名:" + this.name + ";年龄:" + this.age ;
}
}
之后在配置文件中,必须同时设置好key与value。
<bean id="per9" class="org.lxh.ioc.demo09.Person">
  <property name="name">
   <value>zhangsan</value>
  </property>
  <property name="age">
   <value>30</value>
  </property>
  <property name="books">
   <map>
    <entry key="book1">
     <ref bean="book1"/>
    </entry>
    <entry key="book2">
     <ref bean="book2"/>
    </entry>
    <entry key="book3">
     <ref bean="book3"/>
    </entry>
   </map>
  </property>
</bean>
分享到:
评论

相关推荐

    Spring 2.5 jar 所有开发包及完整文档及项目开发实例

     这个jar文件包含Spring一整套mock类来辅助应用的测试。Spring测试套件使用了其中大量mock类,这样测试就更加简单。模拟HttpServletRequest和HttpServletResponse类在Web应用单元测试是很方便的。  如何选择这些...

    spring cloud 体系版本选型,涉及spring cloud alibaba spring boot spring cloud

    在构建基于Spring Cloud的微服务架构时,版本选型是一个至关重要的步骤,它直接影响到系统的稳定性和可维护性。Spring Cloud作为一个广泛使用的微服务框架,其版本迭代迅速,每个版本都有其特定的功能特性和生命周期...

    Spring Boot整合Spring Batch,实现批处理

    在Java开发领域,Spring Boot和Spring Batch的整合是构建高效批处理系统的一种常见方式。Spring Boot以其简洁的配置和快速的启动能力深受开发者喜爱,而Spring Batch作为Spring框架的一部分,专注于批量处理任务,...

    spring的一个适合初学者的项目

    Spring 框架是Java开发中的一个核心框架,尤其对于初学者来说,它是一个极好的起点,可以帮助理解企业级应用的构建方式。本项目旨在为初学者提供一个基础的Spring项目实例,帮助大家快速上手并熟悉Spring的核心概念...

    spring2.0升级到spring3.0.5的开发包

    Spring框架是Java应用程序开发中的一个核心组件,它提供了一个丰富的IOC(Inversion of Control,控制反转)和AOP(Aspect-Oriented Programming,面向切面编程)功能,使得开发者能够更方便地管理对象和实现模块化...

    SpringCloud系列Demo代码,每个子项目都是SpringCloud的一个知识点

    SpringCloud系列Demo代码,每个子项目都是SpringCloud的一个知识点或者说技能点且都有对应的博客介绍,代码开箱即用适合新手学习或老司机复习。 SpringCloud系列Demo代码,每个子项目都是SpringCloud的一个知识点...

    spring教程spring教程spring教程spring教程

    很好的一个spring教程很好的一个spring教程很好的一个spring教程很好的一个spring教程很好的一个spring教程很好的一个spring教程很好的一个spring教程很好的一个spring教程

    Spring的第一个案例

    在"Spring的第一个案例"中,我们将学习如何从零开始创建一个Spring项目。首先,我们需要一个合适的开发环境,如IDEA或Eclipse,以及Spring Initializr来生成初始的项目结构。接着,我们将添加必要的依赖,如Spring ...

    spring第一个学习得例子

    Spring框架是Java开发中的核心组件,它为应用程序提供了一个全面的基础设施,支持bean的管理、依赖注入、AOP(面向切面编程)、MVC(模型-视图-控制器)等特性。"spring第一个学习的例子"旨在帮助初学者快速入门...

    spring 4.3.14(全)最新的spring4正式版

    Spring 框架是 Java 开发中的一个核心组件,它为构建企业级应用程序提供了全面的编程和配置模型。Spring 4.3.14 是该框架的最后一个4.x系列正式版,发布于2018年2月24日。这个版本在Spring 5.0发布之前提供了一个...

    spring boot入门的第一个项目

    Spring Boot 是一个由 Pivotal 团队开发的 Java 框架,旨在简化Spring应用的初始搭建以及开发过程。它预设了许多默认配置,使得开发者能够快速构建可运行的项目,而无需在配置上花费大量时间。本篇文章将深入探讨...

    Spring中文文档下载

    Spring框架是Java开发中的一个核心组件,以其模块化、易用性和灵活性著称。这个压缩包包含Spring的多个中文版本的文档,可以帮助开发者深入理解Spring的功能和使用方法。 `Spring3.0中文版.chm`提供了Spring框架3.0...

    Spring第一章Spring第一章Spring第一章

    在"Spring第一章"中,我们将深入理解Spring框架的基础概念、核心特性以及如何在实际项目中应用。 1. **Spring框架简介** Spring是一个开源的Java平台,提供了一个全面的基础设施,支持开发和部署Java应用程序。它...

    Spring Cloud Gateway 整合 Spring Security 统一登录认证鉴权

    这是一个基于Spring Framework 5,Spring Boot 2 和 Project Reactor 的高性能API网关。它提供了动态路由,服务熔断,负载均衡,以及针对微服务的细粒度控制等功能。通过自定义过滤器,我们可以实现复杂的业务逻辑,...

    Spring5.pdf

    Spring 是一个开源的轻量级Java应用框架,其最初由Rod Johnson创建,并在2003年首次发布。Spring提供了全面的编程和配置模型,其核心特性包括依赖注入(DI)和面向切面编程(AOP)。作为企业级应用开发的基础,...

    一本很好的Spring好书和spring的API

    "一本很好的Spring好书和spring的API"这个资源包含两部分:Spring API的CHM文件和一本Spring入门书籍的PDF,两者都是深入学习Spring框架的重要资料。 首先,让我们来探讨Spring API的CHM文件。CHM(Compiled ...

    spring-cloud项目

    在IT行业中,Spring Cloud是一个非常重要的框架,它构建于Spring Boot之上,为开发分布式系统(如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导选举、分布式会话、集群状态)...

    SpringBatch+Spring+Mybatis+MySql (spring batch 使用jar)

    Spring Batch是一个轻量级的,完全面向Spring的批处理框架,可以应用于企业级大量的数据处理系统。Spring Batch以POJO和大家熟知的Spring框架为基础,使开发者更容易的访问和利用企业级服务。Spring Batch可以提供...

    spring6pdf详细讲解

    Spring 是一个功能强大且功能齐全的 Java 应用程序框架,提供了一个通用的基础结构来支持开发企业级应用程序。 Spring 框架的核心是控制反转(IoC)和依赖注入(DI)模式,它们使得应用程序更加灵活、可维护和可扩展...

    spring-5.3.9-dist.zip(spring-framework-5.3.9)

    Spring框架是Java开发中不可或缺的一部分,它为构建高效、可测试和可维护的应用程序提供了全面的基础设施。在本文中,我们将深入探讨Spring框架的5.3.9版本,包括其核心特性、文档、库和XML架构。 首先,Spring ...

Global site tag (gtag.js) - Google Analytics