Spring IOC理论推导
传统解决用户需求的方法
示例代码
首先父工程需要如下配置 <dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
</dependencies>
新建Maven项目,源码包括dao接口和Service实现,有2个dao接口实现类
UserServiceImpl实例化dao接口实现类,如果调用不同的dao接口实现类,需要修改源码,违背了开闭原则
解决方案
//UserServiceImpl.java
package com.bkms.service;
import com.bkms.dao.UserDao;
public class UserServiceImpl implements UserService {
// 程序控制对象
// private UserDao userDao = new UserDaoImpl();
private UserDao userDao;
public UserDao getUserDao() {
return userDao;
}
//利用set进行动态实现值的注入
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void getUser() {
userDao.getUser();
}
}
//测试客户端
import com.bkms.dao.UserDaoMySQLImpl;
import com.bkms.service.UserService;
import com.bkms.service.UserServiceImpl;
//测试客户端
public class MyTest {
public static void main(String[] args) {
//用户调用业务层不会调用Dao层
UserService userService = new UserServiceImpl();
//set是子类特有的方法,强转的原因是父类无法调用子类特有方法
((UserServiceImpl) userService).setUserDao(new UserDaoMySQLImpl());
//这里补充1点,上面是向下转型,向上转型是为了调用子类已经重写方法或父类未重写方法
//会输出Dao层真正的方法
userService.getUser();
}
}
传统解决用户需求是程序主动创建对象,控制权在程序猿手上使用Set接口实现,程序不再具有主动性,而是变成了
被动的接收对象
这种思想,从本质上解决了问题,程序猿不用管理对象的创建,程序耦合性大大降低,可以专注于业务实现上,这是IOC的原型,下面是配置文件的写法
IOC本质
控制反转(Inversion of Control),是一种设计思想,DL(注入依赖)是实现IOC的一种方法,IOC是Spring框架的核心内容,在Spring中实现控制反转的是IOC容器,实现方法是依赖注入bean在注册进来的时候就会被Spring实例化,走有参或无参,要用的话直接调用getBean拿到引用,然后可以通过引用调用类中的方法,如果getBean同一个id,拿到的就是同一个对象,所以说内存中只有一份实例
示例代码
<?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">
<!--
使用Spring创建对象,在Spring这些成为Bean
id是实例名
class是对象全路径
-->
<bean id="hello" class="com.bkms.pojo.Hello">
<property name="name" value="Spring"/>
</bean>
</beans>
import com.bkms.pojo.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
//获取Spring的上下文对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
//现在我们的Java对象都在Spring中管理了,我们要使用直接从里面拿就可以了
Hello hello = (Hello) applicationContext.getBean("hello");
//调用hello实例的toString方法
System.out.println(hello.toString());
}
}
去掉set注入后,beans.xml中属性字段直接报错
IOC创建对象的方式
- 使用无参构造创建对象,这是默认
- 使用有参构造创建对象,一共有3种有参创建方式
<!--第1种有参创建方式:参数名-->
<bean id="user" class="com.bkms.pojo.User">
<constructor-arg name="name" value="philip"/>
</bean>
<!--第2种有参创建方式:下标赋值-->
<bean id="user" class="com.bkms.pojo.User">
<constructor-arg index="0" value="philip"/>
</bean>
<!--第3种有参创建方式:类型,不建议使用-->
<bean id="user" class="com.bkms.pojo.User">
<constructor-arg type="java.lang.String" value="philip"/>
</bean>
Spring相关配置
- import标签,合并beans到applicationContext.xml
- alias标签,在getBean时可以传入id名,也可以传别名
<!--别名,也可以在bean标签name属性设置别名,并且可以起多个别名,以逗号,空格或分号分割-->
<alias name="user" alias="user2" />