一、IOC容器的运行原理
-
容器:Spring容器是整个核心的载体(如BeanFactory和ApplicationContext)像一个超级工厂负责(既Bean)的创建、管理形成一套生命周期
-
IOC反转控制:IOC本质是一种思想,是根据依赖倒置原则(DIP)来实现的一种规则,其核心是通过对象的创建和依赖关系,将控制权从应用程序代码转移到容器,实现模块间的解耦。
-
依赖注入(DI):依赖注入是IOC的核心实现手段
补充:
DIP原则:高层模块不直接依赖低层模块,二者均依赖抽象(接口/抽象类)。抽象不依赖细节,细节依赖抽象。
解决痛点:
将所有的创建都交给工厂统一管理,而非开发者手动创建,让开发者将重心更倾向于业务代码上
二、Spring IoC 容器定义 XML 配置文件
以下是创建容器配置文件的几种方式
实现类
<bean id="userService" class="org.nf.service.impl.UserServiceImpl"></bean>
- id:表示bean在容器中的唯一标识,在获取bean时是根据id来获取
- class:Bean的完整类名,通过反射创建实例后纳入容器中管理
引言
以上得知bean标签的是通过class属性读取实现类,从而进行让Spring容器接管,那我们是不是也可以将自定义的工厂容器也一并交给Spring容器进行管理
业务接口如下:
public interface UserService {
/**
* 添加用户
*/
void add();
}
前提条件是要给实现类引入接口,例子如下:
public class UserServiceImpl implements UserService {
@Override
public void add() {
System.out.println("添加用户");
}
}
容器的配置文件如下:
1.装配自定义工厂
自定义工厂如下:
public class PeopleServiceFactory {
public UserService create(){
//创建出来的对象也一并会纳入容器中管理
return new PeopleServiceImpl();
}
}
<bean id="peopleServiceFactory" class="org.nf.factory.PeopleServiceFactory"></bean>
<!--装配peoleService对象,注意:这个对象是通过自定义工厂创建出来的
factory-bean:自定义工厂的id
factory-method:自定义工厂的创建方法-->
<bean id="peopleService" factory-bean="peopleServiceFactory" factory-method="create"></bean>
Spring同样将这个工厂视为Bean来管理,也就是所谓的(FactoryBean)
2.装配静态工厂
自定义静态工厂如下:
public class StudentServiceFactory {
public static UserService create(){
return new StudentServiceImpl();
}
}
<bean id="studentService" class="org.nf.factory.StudentServiceFactory" factory-method="create"></bean>
目的是将创建出来的对象纳入容器中,而工厂本身不托管。
为什么说工厂本身不托管,因为通过静态方法是可以通过类名直接调用属于类别,从而不需要容器托管
3.基于FactoryBean来创建受管的Bean对象
public class TeacherServiceFactoryBean implements FactoryBean<UserService> {
/**
* 工厂方法,将创建的对象纳入容器管理
* @return
* @throws Exception
*/
@Override
public UserService getObject() throws Exception {
return new TeacherServiceImpl();
}
/**
* Bean的class类型
* @return
*/
@Override
public Class<?> getObjectType() {
return TeacherServiceImpl.class;
}
/**
* 是否是以单例来管理(默认就是单例模式)
* @return
*/
@Override
public boolean isSingleton(){
return true;
}
}
自定义FactoryBean对象,必须实现Spring提供的FactoryBean接口
<!--3.基于FactoryBean来创建受管的Bean对象-->
<bean id="teacherService" class="org.nf.factory.TeacherServiceFactoryBean"></bean>
Bean的作用域
Bean的作用域可以通过scope属性指定值如下:
singleton(默认项):单例,容器唯一保存的实例
prototype:原型,每次从容器中获取都会重新实例一次
容器配置文件xml如下:
<bean id="userService" class="org.nf.service.impl.UserServiceImpl" scope="prototype"></bean>
测试类如下:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserService s1 = context.getBean(UserService.class);
UserService s2 = context.getBean(UserService.class);
System.out.println(s1);
System.out.println(s2);
通过输出的地址值即可知道两者区别,毋容置疑两者地址值相同则是从容器中拿出的唯一实例,后者相反。
引言
- 在容器底层中Bean标签的相应属性值是由Map集合保存如key保存唯一标识id,value则是存储组件实例。
- 而不同作用域存储的Map也截然不同
单例原理解析如下:
Map<String, Object> singleTon = new HashMap<>();
Object object = clazz.getConstructor() .newInstance();
singleTon.put("userService", object);
从value的类型可知存储的是创建好的实例
原型原理解析如下:
Map<String, Class<?>> prototypeMap = new HashMap<>();
prototypeMap.put("userService", clazz);
Class<?> beanClass = prototypeMap.get("userService");
beanClass.getConstructor().newInstance();
Class<?>是一个泛型类型,可接收任意类的 Class ,而Map的值中存储的是按需创建类的Class,从而通过类来重新实例
来源链接:https://www.cnblogs.com/Mr-Keep/p/18849214
如有侵犯您的版权,请及时联系3500663466#qq.com(#换@),我们将第一时间删除本站数据。
暂无评论内容