Spring核心技术:
IOC(Inverse of control 控制反转):将对象创建权利交给spring工厂进行管理
AOP(Aspect Oriented Programming 面向切面编程):基于动态代理功能增强
spring优势:
(1)方便解耦,简化开发:通过spring提供的IOC容器,可以将对象间的依赖关系交由spring进行控制,避免硬编码所造成的国度程序耦合。用户也不必再为单例模式类,属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
(2)AOP编程的支持:通过spring的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付
(3)声明式事务的支持:可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理,提高开发效率和质量
(4)方便程序的测试:可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情
(5)方便集成各种优秀的框架:spring可以降低各种框架的使用难度,提供了对各种优秀框架的直接支持
(6)降低JavaEE API 的使用难度:spring对JavaEE API(如JDBC,JavaMail,远程调用等)进行了薄薄的封装层,是这些API的使用难度大为降低
1. 创建spring核心配置文件(applicationContext.xml)
(1)引入约束
(2)把类交给spring管理
id属性:id属性是bean的唯一标识
class属性:bean的全路径名
scope属性:scope属性代表bean的作用范围
singleton:单例(默认值)
prototype:多例,在spring框架整合struts2框架的时候,Action类也需要交给spring做管理,配置把Action类配置成多例
request:应用在web应用中,将创建的对象存入到request域中
session:应用在web应用中,将创建的对象存入到session域中
globalsession:应用在porlet环境下使用。将创建的对象存入到全局的session中
init-method属性:当bean被载入到容器中的时候调用init-method属性指定的方法
destroy-method属性:当bean从容器中删除的时候调用destroy-method属性指定的方法(要满足两个条件)
(1)ioc容器一定要显示关闭
(2)bean一定要是单例
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<bean id="userDao" class="cn.itcast.dao.impl.UserDaoImpl"></bean>
</beans>
2. spring中的工厂
spring中提供了两个工厂接口:
(1)ApplicationContext
(2)BeanFactory
2.1 ApplicationContext接口
使用该接口可以获取到具体的Bean对象
该接口下有两个具体的实现类
ClassPathXMLApplicationContext ----加载类路径下的spring配置文件
FileSystemXMLApplicationContext ----加载本地磁盘下的spring配置文件
public class TestIOC {
@Test
public void test1(){
//创建Spring工厂(创建IOC容器)
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) ac.getBean("userDao");
userDao.save();
}
@Test
public void test2(){
//创建Spring工厂(创建IOC容器)
ApplicationContext ac = new FileSystemXmlApplicationContext("C:/spring/applicationContext.xml");
UserDao userDao = (UserDao) ac.getBean("userDao");
userDao.save();
}
}
2.2 BeanFactory工厂
BeanFactory是spring框架早期的创建Bean对象的工厂接口。
@Test
public void test3(){
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
UserDao userDao = (UserDao) factory.getBean("userDao");
userDao.save();
}
BeanFactory和ApplicationContext区别:
BeanFactory采取延迟加载,第一次getBean时才会初始化
ApplicationContext在加载applicationContext.xml时候就会创建具体的Bean对象的实例
3. spring生成bean的三种方式
3.1 无参构造方法
默认调用无参构造方法实例化bean。在此之前,都是调用无参构造来实例化的。
3.2 静态工厂实例化方式(static)
通过调用工厂类的静态方法来生成bean
<bean id="xxx" class=""xxx.xxx.xxx factory-method="xxxx"></bean>
在配置bean时,class属性写工厂类的全路径名。
factory-method:指定工厂类中静态方法的名字
3.3 实例工厂实例化方式(没有static)
<bean id="factory" class="xxx.xxx.Factory"></bean>
<bean id="xxx" factory-bean="factory" factory-method="xxxx"></bean>
factory-bean:指定工厂bean的id
factory-method:指定工厂bean的实例工厂方法
4. 依赖注入
DI:Dependency Injection,依赖注入,在spring康佳负责创建bean对象时,动态的将依赖对象注入到bean组件中!
4.1 构造方法注入
构造方法注入就是利用bean的构造方法完成对bean中的属性的赋值。
创建car实体类,提供有参构造方法
public class Car implements Serializable{
private static final long serialVersionUID = 1L;
private String name;
private Double price;
public Car(String name, Double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public String toString() {
return "Car [name=" + name + ", price=" + price + "]";
}
}
<!-- 构造方法注入 -->
<bean id="car" class="xxx.xxx.car">
<constructor-arg name="name" value="xxx"></constructor-arg>
<constructor-arg name="price" value="33.3"></constructor-arg>
</bean>
name:bean中的属性 value:想要赋的值
4.2 set方法注入
set方法注入就是利用bean中属性的set方法对属性赋值。
创建People实体类,提供属性的set方法,不需要提供有参构造方法。
public class People implements Serializable {
private static final long serialVersionUID = 1L;
private String name;//要提供属性所对应的set方法
private String address;
private Car car;//对象属性
public void setName(String name) {
this.name = name;
}
public void setAddress(String address) {
this.address = address;
}
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return "People [name=" + name + ", address=" + address + ", car=" + car + "]";
}
}
<!-- set方法注入 -->
<bean id="people" class="cn.itcast.domain.People">
<property name="name" value="小明"></property>
<property name="address" value="上海"></property>
<property name="car" ref="car"></property>
</bean>
配置people实体类,普通属性用value指定值,对象属性用ref指定需要注入的bean的id
4.3 set方法其他注入写法
(1)p命名空间写法
在约束中引入p命名空间。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- set方法注入:p命名空间 -->
<bean id="people" class="xxx.xxx.people" p:name="小刚" p;address="北京" p:car-ref="car"></bean>
(2)SpEL的写法(spring3.0提供)
SpLE:Spring Expression Language
<!-- set方法注入:SpEL -->
<bean id="people" class="cn.itcast.domain.People">
<property name="name" value="#{'小明'}"></property>
<property name="address" value="#{'上海'}"></property>
<property name="car" value="#{car}"></property>
</bean>
SpEL注入语法:
注入字符串:#{‘字符串’}
注入数字:#{数字}
注入其他对象:#{对象id}
SpEL还可以注入其它对象的属性或方法的返回值,创建CarInfo类,存储Car的信息:
public class CarInfo {
public String getCarName(){
return "宝骏560";
}
public double calculatePrice(){
return Math.random() * 10000;
}
}
创建Car2实体类:
public class Car2 implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private Double price;
public void setName(String name) {
this.name = name;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public String toString() {
return "Car [name=" + name + ", price=" + price + "]";
}
}
配置Car2:
<!-- SpEL的写法 -->
<bean id="carInfo" class="xxx.xxx.CarInfo"></bean>
<bean id="car2" class="xxx.xxx.Car2">
<property name="name" value="#{carInfo.name}"></property>
<property name="price" value="#{carInfo.calculatePrice()}"></property>
</bean>
4.4 数组和list注入(数组(array)和list注入写法是一样的)
新建bean类:CollectionBean
public class CollectionBean implements Serializable{
private static final long serialVersionUID = 1L;
private List<String> list;//也可以是数组
public void setList(List<String> list) {
this.list = list;
}
@Override
public String toString() {
return "CollectionBean [list=" + list + "]";
}
}
配置
<!-- 特殊类型的注入 -->
<bean id="cb" class="cn.itcast.domain.CollectionBean">
<property name="list">
<list>
<value>你</value>
<value>我</value>
<value>他</value>
</list>
</property>
</bean>
6.5 set集合注入
在CollectionBean添加一个Set类型的属性并提供set方法:
public class CollectionBean implements Serializable{
private static final long serialVersionUID = 1L;
private Set<String> set;
public void setSet(Set<String> set) {
this.set = set;
}
@Override
public String toString() {
return "CollectionBean [list=" + list + ", set=" + set + "]";
}
}
配置:
<property name="set">
<set>
<value>天</value>
<value>地</value>
<value>人</value>
</set>
</property>
提示:spring在注入set的时,给我们注入的是一个LinkedHashSet,所以在输入set集合中的元素时,是按照我们注入的顺序来的,并不是无序的。
6.6 map集合的注入
在CollectionBean添加一个Map类型的属性并提供set方法:
public class CollectionBean implements Serializable
private static final long serialVersionUID = 1L;
private Map<String,String> map;
public void setMap(Map<String, String> map) {
this.map = map;
}
@Override
public String toString() {
return "CollectionBean [map=" + map + "]";
}
}
<property name="map">
<map>
<entry key="id" value="1"></entry>
<entry key="username" value="张三"></entry>
</map>
</property>
说明:
<entry>表示map中的键值对
<entry>中的key表示键,value表示值
6.7 Properties(配置文件)的注入
在CollectionBean添加一个Properties类型的属性并提供set方法:
public class CollectionBean implements Serializable{
private static final long serialVersionUID = 1L;
private Properties properties;
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public String toString() {
return "CollectionBean [ properties=" + properties + "]";
}
}
配置:
<property name="properties">
<props>
<prop key="id">2</prop>
<prop key="name">小明</prop>
</props>
</property>
<prop>:表示一个键值对
<prop>中的key表示键,在<prop></prop>中写的是值
6.8 配置文件分离
spring配置文件分离有两种方式:
(1)在applicationContext中采用import标签导入另一个配置文件
现在,在整个工程中有applicationContext.xml和applicationContext2.xml两个配置文件。可以把aplicationContext.xml看成一个总的配置文件,在其中包含applicaitonContext2.xml文件。
<improt resource="applicationContext2.xml"/>
此时,创建IOC容器时,只需要加载applicationContext.xml即可,因为在applicationContext.xml引入了applicationContext2.xml,所以,applicationContext2.xml也会加载
(2)在实例化ApplicationContext的时候,指定多个配置文件。
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml","applicationContext2.xml");