Spring基础知识
Spring为企业应用开发提供了一个一站式的解决方案。它将各种设计模式的功能进行了实现,并且封装起来以便使用。
使用Spring框架时,必须使用Spring Core Container,即Spring容器,它是Spring框架的核心机制。由org.springframework.core、org.springframework.context、org.springframework.beans、org.springframework.experssion四个Jar包组成。
使用Spring,登陆:http://repo.springsource.org/lib-release-loacl/站点进行下载。得到spring-framework-x.x.x.RELEASE-dist.zip文件。解压后有以下几个子文件:
docs:存放Spring相关的文档。
libs:存放三类Jar包。Spring框架class文件的Jar包、Spring框架源文件的压缩包、Spring框架Api文档压缩包。
schemas:存放Spring各种配置文件的XML schema文档
将libs目录下相关的class文件的Jar包复制添加到项目的类加载目录。
使用Maven的话,添加相应的依赖即可:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
不使用IDE工具的话,可以添加到环境变量。发布时这些Jar包也一同发布就行(比如发布web项目,需要把Jar包导入WEB-INF路径下)。
重要的是:Spring必须依赖common-llogging的Jar包。
Spring核心容器的理论是:Spring核心容器是一个大工厂,所有的对象在其中称为Bean。
Spring通过XML配置文件来管理Bean。
*IOC:控制反转(Inverse of Control):就是将原本在程序中手动创建对象的控制权交给Spring。其底层逻辑是:使用工厂+反射+配置文件的方式,通过工厂类对配置文件进行解析,以获取相应的类的实例对象。。
ioc的底层逻辑:使用工厂类解析:<bean id="idxx" class="com.imoox.PersonImpl">,工厂类中有对应id作为参数的方法。当传入不同的id值,就解析出不同的class值。利用class值,也就是全限定类名,反射得到相应的类对象。工厂中会执行的代码简单表示如下:
String idStr = idxxx //对应解析<bean>元素的id值。
String classStr = ... //对应解析<bean>元素的class值。
Class clazz = Class.forName(classStr) //得到classStr对应类的Class对象。
Object obj = clazz.newInstance() //得到Class对象实例
container.put(idStr,obj) //以ID作为Key值,将class对应的对象放入容器中。
*DI:依赖注入:在Spring创建对象的过程中,将对象所依赖的属性注入进去。比如,底层实现类需要添加一个属性,在调用层就不需要使用setter方法,直接在配置文件中使用<property>注入即可。
下面以IDEA示例进行解释:
创建了一个maven项目,需要在resources文件夹下新建配置文件:applicationContext.xml:
<?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">
<!--UserService的创建权交给了Spring-->
<bean id="userService" class="com.imooc.ioc.demo1.UserServiceImpl">
<!--设置属性-->
<property name="name" value="李四"></property>
</bean>
</beans>
配置文件很简单,根目录是<beans.../>,它可以包含多个<bean>元素,每个<bean>元素定义一个Bean。上面定义了一个id为userService的Bean,他的全限定类名为:com.imooc.ioc.demo1.UserServiceImpl。
下面是UserService接口:
package com.imooc.ioc.demo1;
public interface UserService {
public void sayHello();
}
下面是其实现类:UserServiceImpl
package com.imooc.ioc.demo1;
public class UserServiceImpl implements UserService {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void sayHello(){
System.out.println("Hello Spring"+name);
}
}
在配置文件中我们可以看到,已经配置了id=userService的bean元素,其指向了UserServiceImpl类。并且设置了name属性。
可以通过如下的代码测试:
package com.imooc.ioc.demo1;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
public class SpringDemo1 {
@Test
/**
* 传统方式开发
*/
public void demo1() {
UserService userService = new UserServiceImpl();
userService.sayHello();
}
@Test
/**
* Spring的方法实现
*/
public void demo2() {
//创建Spring的工厂
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) applicationContext.getBean("userService");
userService.sayHello();
}
}
在demo2测试方法中,使用了Spring。基本的步骤是:
1:创建Spring的工厂:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
ApplicationContext是Spring容器最常用的接口,该接口有两个实现类:
ClassPathXmlAppliacationContext:从类加载路径下搜索配置文件,并根据文件创建工厂容器。
FileSystemXmlApplicationConetxt:从文件系统的相对路径或绝对路径搜索配置文件,并根据文件创建工厂容器。
对于Java项目而言,类加载路径总是一定的,因此常用ClassPathXmlApplicationContext实现类。
IDEA下,配置文件resource文件,编译后会自动放在类加载路径下。手动发布项目的话,如Web项目,配置文件源码应该和java源码放在同一个路径src下。
这一步在Spring的底层就是进行了IOC实现,Spring解析配置文件中的<bean>,可以得到两个字符串:
String idStr = bean元素的id值。
String clsssStr = bean元素的class值,也就是指定的全路径类名。
通过反射获取类的Class对象:Class clazz = Class.forName(classStr)
通过Class对象获取类的实例:Object obj = clazz.newInstance();
将id值和类实例放到容器中:contaier.put(idStr,obj)。
2:获取Bean对象:
UserService userService = (UserService)applicationContext.getBean("userService");
Spring容器获取Bean对象主要有两个方法:
Object getBean(String id):根据容器中Bean的id来获取指定Bean。
T getBean(String name,Class<T> requiredType):根据容器中Bean的id来获取指定Bean,带有泛型参数,无需强制类型转换。
可以这么理解:每个<bean>元素驱动Spring调用该类无参构造器来创建实例。实例以键值对方式放在了容器中,然后调用getBean方法时,传入id作为key,就找到了该实例。
获取Bean对象后,就相当于获取了原本类的实例,该怎么用怎么用。