简介
上文中提到,Spring主要是管理各种bean。
loC: Inverse of Control (反转控制)
- 将原本在程序中手动创建对象的控制权,交由Spring框架来管理。
正控
:若要使用某个对象,需要自己去负责对象的创建反控
:若要使用某个对象,只需要从Spring容器中获取需要使用的对象,不关心对象的创建过程,也就是把创建对象的控制权反转给了Spring框架
DI: Dependency Injection(依赖注入)
- IoC的另外一种说法,指的是Spring容器初始化Bean的方法为依赖注入
控制反转是一种通过描述(在Spring中可以是XML或注解)并通过第三方去产生或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入。(这里的XML即applicationContext.xml)
Spring IoC容器
注:配置文件如何书写在SpringBean文章中
2.1 BeanFactory接口
BeanFactory
提供了完整的IoC服务支持,是一个管理Bean的工厂,主要负责初始化各种Bean。创建BeanFactory实例时,需要提供XML文件的绝对路径。
BeanFactory 接口有多个实现类,最常见的是org.springframework.beans.factory.xml.XmlBeanFactory
,它是根据 XML 配置文件中的定义装配 Bean 的。
public static void main(String[] args){
//初始化Spring容器,加载配置文件
BeanFactory beanFac = new XmlBeanFactory(new FileSystem Resource("D:\\eclipse-workspace\\ch1\\src\\applicationContext.xml"));
//通过容器获取test实例
TestDaott=(TestDao)beanFac.getBean("test");
tt.sayHello();
}
复制代码
2.2 ApplicationContext接口
ApplicationContext
是BeanFactory的子接口,也称为应用上下文,由org.springframework.context.ApplicationContext
接口定义。ApplicationContext接口除了包含BeanFactory的所有功能以外,还添加了对国际化、资源访问、事件传播等内容的支持。
创建ApplicationContext实例,通常有三种方法:
1.通过ClassPathXmlApplicationContext创建
- 类路径classPath目录(src根目录)寻找指定的XML配置文件(classPath:WEB-INF/classes/)
public static void main(String[] args){
//初始化Spring容器ApplicationContext,加载配置文件
ApplicationContext appCon=new ClassPathXmlApplicationContext("applicationContext.xml");
//通过容器获取test实例
TestDao tt=(TestDao)appCon.getBean("test");
tt.sayHello();
}
复制代码
2.通过FileSystemXmlApplicationContext创建
- 绝对路径寻找XML配置文件
public static void main(String[] args){
//初始化Spring容器ApplicationContext,加载配置文件
ApplicationContext appCon=new FileSystemXmlApplicationContext ("D:\\eclipse-workspace\\ch1\\src\\applicationContext.xml");
//通过容器获取test实例
TestDao tt=(TestDao)appCon.getBean("test");
tt.sayHello();
}
复制代码
3.通过Web服务器实例化ApplicationContext容器创建
2.3 区别
如果 Bean 的某一个属性没有注入:
- BeanFacotry 加载后,第一次调用 getBean() 方法时会抛出异常,
- ApplicationContext 则在初始化时自检,有利于检查所依赖的属性是否注入。
因此在实xt,只有系统资源较少时,才使用 BeanFactory。
属性值注入方法
新建Maven项目,导入必要包
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>www.xaut.edu.cn.software</groupId>
<artifactId>testmaven1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</project>
复制代码
3.1 构造方法注入
使用constructor-arg
标签
Tmp.java
//为了展示成员为其他类的时候,在xml中使用ref指定成员属性
package com.dao;
public class Tmp {
//构造方法,用于依赖注入
public Tmp() {}
void work(){
System.out.println("Tmp.work()");
}
}
复制代码
TestDao.java
package com.dao;
public interface TestDao {
public void work();
}
复制代码
TestDaoImpl.java
package com.dao;
public class TestDaoImpl implements TestDao{
int a;
Tmp b;
//构造方法,用于实现依赖注入
public TestDaoImpl(int a,Tmp b){
super();
this.a = a;
this.b = b;
}
@Override
public void work() {
System.out.println("a = "+a);
b.work();
}
}
复制代码
application.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="tmp" class="com.dao.Tmp"></bean>
<bean id="test" class="com.dao.TestDaoImpl">
<constructor-arg index="0" value="1" />
<constructor-arg index="1" ref="tmp" />
</bean>
</beans>
复制代码
Test.java
package com.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.dao.TestDao;
public class Test {
public static void main(String args[]) {
@SuppressWarnings("resource")
ApplicationContext appCon = new ClassPathXmlApplicationContext("applicationContext.xml");
TestDao tmp = (TestDao)appCon.getBean("test");
tmp.work();
}
}
复制代码
3.2 属性setter方法注入
调用无参构造器或无参static工厂方法实例化 bean 后,调用该 bean 的 setter 方法。
使用property
标签
其他文件与上文相同)
TestDaoImpl.java
package com.dao;
public class TestDaoImpl implements TestDao{
private int a;
private Tmp b;
public void setA(int a) {
this.a = a;
}
public void setB(Tmp b) {
this.b = b;
}
@Override
public void work() {
System.out.println("a = "+a);
b.work();
}
}
复制代码
application.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="tmp" class="com.dao.Tmp">
</bean>
<bean id="test" class="com.dao.TestDaoImpl">
<property name="a" value="1" />
<property name="b" ref="tmp" />
</bean>
</beans>
复制代码