IOC:控制反转,控制权的转移,应用程序本身不负责依赖对象的创建和维护,而是由外部容器负责创建和维护。
DI(依赖注入)是其一种实现方式。
目的:创建对象并且组装对象之间的关系。
Spring通过一个配置文件描述Bean和Bean之间的依赖关系,利用Java语言的反射功能(https://blog.csdn.net/m0_37657841/article/details/89014787)实例化Bean并建立Bean之间的依赖关系。
Bean工厂(com.springframework.beans.factory.BeanFactory)是Spring是框架最核心的接口,它提供了高级IoC的配置机制。应用上下文((com.springframework.context.ApplicationContext)建立在BeanFactory的技术上,提供了更多面向应用的功能。
1、BeanFactory
Spring为BeanFactory提供了多种实现,最常用的是XMLBeanFactory,但在Spring3.2中已经废弃,建议使用XMLBeanDefinitionReader、DefaultListableBeanFactory代替。
一个简单的例子:
先定义一个简单的bean
public class Car {
private String brand;
private String color;
private int maxSpeed;
public Car(){System.out.println("init car!!");}
public Car(String brand,String color,int maxSpeed){
this.brand = brand;
this.color = color;
this.maxSpeed = maxSpeed;
}
public void introduce() {
System.out.println("brand:"+brand+";color:"+color+";maxSpeed:"+maxSpeed);
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
}
配置beans.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" 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">
<bean id="car" class="com.smart.reflect.Car" p:brand="红旗CA72" p:color="black" p:maxSpeed="100"/>
</beans>
通过XMLBeanDefinitionReader、DefaultListableBeanFactory实现类启动Spring IoC容器。
import com.smart.reflect.Car;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.testng.annotations.*;
/**
* @author KiroScarlet
* @date 2019-04-16 -13:34
*/
public class BeanFactoryTest {
@Test
public void getBean() throws Throwable {
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
//加载资源路径
Resource res = resolver.getResource("classpath:com/smart/beanfactory/beans.xml");
System.out.println(res.getURL());
// 被废弃,不建议使用
// BeanFactory bf = new XmlBeanFactory(res);
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(res);
System.out.println("init beanfactory");
Car car = factory.getBean("car", Car.class);
car.introduce();
}
}
2、ApplicationContext
如果说BeanFactory是Spring的“心脏”,那么ApplicationContext就是完整的“身躯”了。
ApplicationContext的主要实现类是ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,前者默认从类路径加载配置文件,后者默认从文件系统中装载配置文件。
//类路径方式,默认为classpath
ApplicationContext ctx1 = new ClassPathXmlApplicationContext("com/smart/beanfactory/beans.xml");
//文件系统方式,默认为file
ApplicationContext ctx2 = new FileSystemXmlApplicationContext("src/main/resources/com/smart/beanfactory/beans.xml");
基于类注解的方式
和基于xml的方式相比,基于类注解的方式更加简单灵活。需要首先提供一个配置类。
@Configuration
public class Beans {
@Bean(name = "car")
public Car buildCar() {
Car car = new Car();
car.setBrand("红旗CA72");
car.setMaxSpeed(200);
return car;
}
}
Spring为基于注解类的配置提供了专门的ApplicationContext实现类AnnotationApplicationContext:
public class AnnotationApplicationContextTest {
@Test
public void getBean() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(Beans.class);
Car car = ctx.getBean("car", Car.class);
assertNotNull(car);
}
}