佟刚Spring4.0学习笔记

2018-02-27 10:59:40来源:oschina作者:情话撩人人点击

分享
1.概述

Spring是一个Java领域的开源框架,它为简化企业级应用开发而生,可以使用简单的JavaBean实现以前只有EJB才能实现的功能。


1.1.特性轻量级(非侵入性):基于Spring开发的时候,我们不需要实现Spring提供的任何接口,也不需要继承Spring提供的任何类,然后我们就可以使用Spring给我们提供的功能
依赖注入(DI-Dependency Injection)
面向切面编程(AOP-Aspect Oriented Programming)
一站式框架:在IOC和AOP的基础上可以整合各种企业级开源框架和优秀的第三方类库
组件组合:Spring实现了使用简单的组件组合成一个复杂的应用,可以使用XML和Java注解组合这些组件 1.2.模块


1.3.配置文件

一个典型的Spring项目需要创建一个或多个Bean配置文件,Bean配置文件可以放在Classpath下,也可以放在其它目录下。


2.Hello World

HelloWorld.java


package org.lin.stu.spring;
public class HelloWorld {
private String name;
public void setName(String name) {
this.name = name;
}
public void say() {
System.out.println("Hello " + name);
}
}2.1.传统方式
//创建HelloWorld的一个对象
HelloWorld helloWorld = new HelloWorld();
//为name属性赋值
helloWorld.setName("World");
//调用方法
helloWorld.say();//Hello World2.2.使用Spring
<?xml version="1.0" encoding="UTF-8"?>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">





//创建Spring的IOC容器,ClassPathXmlApplicationContext表示配置以XML文件的形式存放在类路径下
//创建IOC容器后会立即初始化(即创建并初始化配置的Bean)
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//从IOC容器中获取Bean
HelloWorld helloWorld = (HelloWorld) ctx.getBean("helloWorld");
//调用方法
helloWorld.say();//Hello World
3. Bean配置
3.1.在XML文件中通过bean节点来配置Bean
//class属性值为全类名,即Spring通过反射的方式创建Bean


id(Bean的名称):

在IOC容器中必须是唯一的
若id没有指定,Spring将自动生成,格式为:全类名#数字(例如:org.lin.stu.spring.HelloWorld#0) 3.2.BeanFactory&ApplicationContext

BeanFactory是IOC容器的基本实现,ApplicationContext提供了更多的高级特性,是BeanFactory的子接口。


BeanFactory是Spring框架的基础设施,面向Spring本身,而ApplicationContext面向使用Spring框架的开发者,几乎所有的应用场合都直接使用ApplicationContext而非底层的BeanFactory。


3.3.ApplicationContextApplicationContext的主要实现类:

ClassPathXmlApplicationContext:从类路径下加载配置文件
FileSystemXmlApplicationContext:从文件系统中加载配置文件IOC容器初始化时就创建并初始化所有的单例Bean
WebApplicationContext是专门为WEB应用而准备的 3.4.通过类型获取Bean
HelloWorld helloWorld = ctx.getBean(HelloWorld.class);

如果IOC容器中有多个同类型的Bean,则抛出NoUniqueBeanDefinitionException异常。


3.5.依赖注入

Spring支持3种依赖注入方式

属性注入
构造器注入
工厂方法注入(很少使用,不推荐) 3.5.1.属性注入属性注入即通过set方法注入Bean的属性值或依赖的对象
属性注入使用元素,name属性指定Bean的属性名,value属性或子节点指定属性值
属性注入是实际应用中最常用的注入方式 3.5.2.构造器注入

通过构造器注入Bean的属性值或依赖的对象


Car.java


package org.lin.stu.spring;
public class Car {
private String brand;//品牌
private Double price;
private Integer maxSpeed;
public Car() {
}
public Car(String brand, Double price) {
this.brand = brand;
this.price = price;
}
public Car(String brand, Integer maxSpeed) {
this.brand = brand;
this.maxSpeed = maxSpeed;
}
//getters and setters are omitted
}






以上代码等价于:









ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Car car1 = (Car) ctx.getBean("car1");
Car car2 = (Car) ctx.getBean("car2");
System.out.println(car1);//Car{brand='Audi', price=null, maxSpeed=300000}
System.out.println(car2);//Car{brand='Audi', price=null, maxSpeed=240}

因为300000和240既可以匹配Double也可以匹配Integer,此时仅靠顺序无法实现目的。


可以通过type属性避免上述问题:









240

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Car car1 = (Car) ctx.getBean("car1");
Car car2 = (Car) ctx.getBean("car2");
System.out.println(car1);//Car{brand='Audi', price=300000.0, maxSpeed=null}
System.out.println(car2);//Car{brand='Audi', price=null, maxSpeed=240}
3.6.字面值可用字符串表示的值(基本数据类型及其封装类型、String等类型),可以通过标签或value属性进行注入
若字面值中包含特殊字符(例如<等字符),可以使用把字面值包裹起来,但只能通过标签方式注入,例如:]]> 3.7. 引用其它Bean组成应用程序的Bean经常需要相互协作以完成应用程序的功能
在Bean的配置文件中,可以通过标签或ref属性为Bean的属性或构造器参数指定引用的Bean
也可以在属性或构造器里包含Bean的声明,这样的Bean称为内部Bean package org.lin.stu.spring;
public class Person {
private String name;
private Car car;
//getters and setters are omitted
}
package org.lin.stu.spring;
public class Car {
private String brand;
private Double price;
private Integer maxSpeed;
//getters and setters are omitted
}










ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person) ctx.getBean("person");
System.out.println(person);//Person{name='Alan', car=Car{brand='Audi', price=300000.0, maxSpeed=null}}
3.8. 内部Bean当某个Bean仅在某个地方使用时,可以将其声明为内部Bean,内部Bean声明直接包含在标签里,不需要设置id属性
内部Bean不能使用在任何其他地方 package org.lin.stu.spring;
public class Person {
private String name;
private Car car;
//getters and setters are omitted
}
package org.lin.stu.spring;
public class Car {
private String brand;
private Double price;
private Integer maxSpeed;
//getters and setters are omitted
}









ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person) ctx.getBean("person");
System.out.println(person);//Person{name='Alan', car=Car{brand='Audi', price=300000.0, maxSpeed=null}}
3.9. 空值和级联属性可以使用标签为Bean的属性注入null值
Spring支持级联属性的配置





3.10. 集合属性可以使用一组内置的XML标签(例如:)配置集合属性
java.util.List类型的属性需要使用标签配置,在标签里配置一些元素,这些元素可以是元素(配置字面值),也可以是元素(指定对其他Bean的引用),还可以是元素(配置内置Bean),还可以是元素,甚至可以内嵌其他集合
数组和List一样,也使用标签
java.util.Set类型的属性需要使用标签配置,配置方法与List一样
java.util.Map类型的属性需要使用标签配置,标签里可以使用多个标签,每个标签包含一个键和一个值,因为键和值的类型没有限制,所以可以自由地使用,标签为它们指定值,可以通过属性指定键和值,简单值通过key和value属性指定,Bean引用通过key-ref和value-ref属性指定
java.util.Properties类型的属性需要使用标签配置,标签里可以使用多个标签,每个标签必须指定key属性 3.10.1. List
package org.lin.stu.spring;
public class Car {
private String brand;
private Double price;
private Integer maxSpeed;
//getters and setters are omitted
}
package org.lin.stu.spring;
import java.util.List;
public class Person {
private String name;
private List cars;
//getters and setters are omitted
}












ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person) ctx.getBean("person");
System.out.println(person);//Person{name='Mike', cars=[Car{brand='Audi', price=300000.0, maxSpeed=null}]}
3.10.2. Map
package org.lin.stu.spring;
public class Car {
private String brand;
private Double price;
private Integer maxSpeed;
//getters and setters are omitted
}
package org.lin.stu.spring;
import java.util.Map;
public class Person {
private String name;
private Map cars;
//getters and setters are omitted
}












ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person) ctx.getBean("person");
System.out.println(person);//Person{name='Mike', cars={A=Car{brand='Audi', price=300000.0, maxSpeed=null}}}
3.10.3. Properties
package org.lin.stu.spring;
import java.util.Properties;
public class DataSource {
private Properties properties;
//getters and setters are omitted
}



root
123
jdbc:mysql///test
com.mysql.jdbc.Driver



ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = (DataSource) ctx.getBean("dataSource");
System.out.println(dataSource);
//DataSource{properties={password=123, driverClass=com.mysql.jdbc.Driver, url=jdbc:mysql///test, username=root}}
3.11. 使用util scheme配置集合属性使用基本的集合标签配置集合时,不能将集合作为独立的Bean定义,导致其他Bean无法引用该集合,所以无法在不同Bean之间共享该集合
可以使用util schema里的集合标签配置独立的集合Bean 3.10. 自动装配

Spring IOC容器可以自动装配Bean,需要做的仅仅是通过的autowire属性指定自动装配的模式

byType(根据类型自动装配):若IOC容器中有多个类型匹配的Bean,则抛出NoUniqueBeanDefinitionException异常
byName(根据名称自动装配):必须将目标Bean的名称和setter风格的属性名设成一样
constructor(通过构造器自动装配):当类中存在多个构造器时,此种自动装配方式将会很复杂,不推荐使用 package org.lin.stu.spring.autowire;
public class Person {
private String name;
private Address address;
private Car car;
//getters and setters are omitted
}
package org.lin.stu.spring.autowire;
public class Address {
private String city;
private String street;
//getters and setters are omitted
}
package org.lin.stu.spring.autowire;
public class Car {
private String brand;
private Double price;
//getters and setters are omitted
}

byName:





ApplicationContext ctx = new ClassPathXmlApplicationContext("autowire.xml");
Person person = (Person) ctx.getBean("person");
System.out.println(person);//Person{name='Tom', address=Address{city='ChengDu', street='ShengBangJie'}, car=Car{brand='Audi', price=300000.0}}

byType:





ApplicationContext ctx = new ClassPathXmlApplicationContext("autowire.xml");
Person person = (Person) ctx.getBean("person");
System.out.println(person);//Person{name='Tom', address=Address{city='ChengDu', street='ShengBangJie'}, car=Car{brand='Audi', price=300000.0}}
3.10.1. 自动装配的缺点在Bean配置文件里设置autowire属性进行自动装配将会装配Bean的所有属性
autowire属性要么根据类型自动装配,要么根据名称自动装配,不能两者兼而有之
一般情况下,在实际的项目中很少使用自动装配功能,因为和自动装配功能所带来的好处比起来,明确清晰的配置文档更有说服力 3.11. Bean之间的继承关系Spring允许继承Bean的配置,被继承的Bean称为父Bean,继承这个父Bean的Bean称为子Bean
子Bean从父Bean中继承配置,包括Bean的属性配置
子Bean也可以覆盖从父Bean继承过来的配置
父Bean可以作为配置模板,也可以作为Bean实例,若只想把父Bean作为模板,可以设置的abstract属性为true,这样Spring将不会实例化这个Bean
并不是元素里的所有属性都会被继承,比如:autowire,abstract等
也可以忽略父Bean的class属性,让子Bean自己指定,而共享相同的属性配置,但此时该Bean必须是抽象Bean package org.lin.stu.spring.relation;
public class Address {
private String city;
private String street;
//getters and setters are omitted
}


ApplicationContext ctx = new ClassPathXmlApplicationContext("relation.xml");
Address address1 = (Address) ctx.getBean("address1");
Address address2 = (Address) ctx.getBean("address2");
System.out.println(address1);//Address{city='ChengDu', street='YuLinLu'}
System.out.println(address2);//Address{city='ChengDu', street='BaiCaoLu'}
3.12. Bean之间的依赖关系Spring允许通过depends-on属性设置依赖的Bean,依赖的Bean会在本Bean实例化之前创建好,如果容器中没有依赖的Bean,则会抛出NoSuchBeanDefinitionException异常
如果依赖于多个Bean,可用逗号或空格进行分隔

3.15.使用外部属性文件

在Spring的配置文件里配置Bean时,有时需要在Bean的配置里混入系统部署的细节信息(例如:文件上传目录、数据源配置信息等)
Spring提供了一个PropertyPlaceholderConfigurer的BeanFactory后置处理器,这个后置处理器允许用户将Bean配置的部分内容外移到属性文件中,在Bean配置文件里使用${var}代替,PropertyPlaceholderConfigurer从属性文件里加载属性,并使用这些属性来替换变量
Spring还允许在外部属性文件中使用${propName},以实现属性之间的相互引用

3.15.1. 配置


Spring2.5之前:





Spring2.5之后,新增加了更加简便的方式:



示例:


package org.lin.stu.spring.properties;
public class DataSource {
private String user;
private String password;
private String driverClass;
private String jdbcUrl;
//getters and setters are omitted
}

db.properties


user=root
password=${user}
driverClass=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql:///test







ApplicationContext ctx = new ClassPathXmlApplicationContext("properties.xml");
DataSource dataSource = (DataSource) ctx.getBean("dataSource");
System.out.println(dataSource);//DataSource{user='root', password='root', driverClass='com.mysql.jdbc.Driver', jdbcUrl='jdbc:mysql:///test'}

最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台