一、IOC本质
- 控制反转时一种通过描述(xml或注解)并通过第三方去生产或获取特定对象的方式。在spring中实现控制反转的时ioc容器,其实现方式是依赖注入(DI)。
1、编写接口
public interface UserDao {
void getUser();
}
2、编写两个不同的实现类
public class UserDaoImpl implements UserDao{
public void getUser(){
System.out.println("默认获取用户的数据!");
}
}
public class UserDaoMysqlImpl implements UserDao{
@Override
public void getUser() {
System.out.println("默认获取mysql的数据!");
}
}
3、编写service和实现类
- 第一种:原本做法
- service
public interface UserService { void getUser(); }
- serviceImpl
public class UserServiceImpl implements UserService { //此时修改需求的话,需要改变这里的代码,控制权在程序员手上 private UserDao userDao = new UserDaoMysqlImpl(); public void getUser() { userDao.getUser(); } }
- 第二种:IOC控制反转
- service
public interface UserService { void setUserDao(UserDao userDao); void getUser(); }
- serviceImpl
public class UserServiceImpl implements UserService { //利用set进行动态实现值的注入 private UserDao userDao; public void setUserDao(UserDao userDao){ this.userDao = userDao; } public void getUser() { userDao.getUser(); } }
4、测试
1.第一种【原始】
@Test
public void test(){
UserService service = new UserServiceImpl();
service.getUser();
}
- 这里我们每一次增加dao实现类,去实现的时候就要取修改serviceImpl中的代码
private UserDao userDao = new UserDaoMysqlImpl();
- 控制权在程序员手上
2、第二种【IOC】
public void test(){
UserService userService = new UserServiceImpl();
userService.setUserDao(new UserDaoImpl());
userService.getUser();
}
- 用户实际调用的是业务层,dao层他们不需要接触,通过serviceImpl中的set注入
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
- 此时需求改变不会影响源代码,控制权在用户手上
5、使用spring
1.使用配置文件实现注入
<?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-->
<bean id="UserDaoImpl" class="com.lc.demo01.UserDaoImpl"/>
<bean id="userDaoMysql" class="com.lc.demo01.UserDaoMysqlImpl"/>
<!--
ref:引用Spring容器中创建好的对象
value:具体的值,基本数据类型
此时用户需求改变,只需改变ref中的内容,换成所需的对象名
-->
<bean id="userService" class="com.lc.service.UserServiceImpl">
<property name="userDao" ref="userDaoMysql"/>
</bean>
</beans>
2.测试
public void test(){
//获取application context拿到Spring的容器
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//获取到容器之后,需要什么直接,get什么就行。
UserServiceImpl userServiceImpl = (UserServiceImpl) context.getBean("userService");
userServiceImpl.getUser();
}
3.结果
2、IOC创建对象的方式
1、使用无参构造创建对象【默认】
1.创建实体类【构成函数无参】
public class User {
private String name;
public User(){
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void show(){
System.out.println("无参构造函数"+"name="+name);
}
}
2.在xml中注册bean
<bean id="user" class="com.lc.demo01.User">
<property name="name" value="lincong"/>
</bean>
<!--别名,可以通过别名来获取。-->
<alias name="user" alias="user0"/>
3.测试
@Test
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
User user = (User)context.getBean("user0");
user.show();
}
4.结果
2、使用有参构造创建对象
1、创建实体类【有参构造】
public class UserT {
private String name;
public UserT(String name){
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void show(){
System.out.println("有参构造函数"+"name="+name);
}
}
2、在xml中注册bean
- 下标赋值
<bean id="userT1" class="com.lc.dao.UserT">
<constructor-arg index="0" value="lincong1"/>
</bean>
- 参数类型赋值(不建议使用)
<bean id="userT2" class="com.lc.dao.UserT">
<constructor-arg type="java.lang.String" value="lincong2"/>
</bean>
- 根据实体类中的参数名称赋值(自定义)
<bean id="userT3" class="com.lc.dao.UserT">
<constructor-arg name="name" value="lincong3"/>
</bean>
3、测试
@Test
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserT userT = (UserT)context.getBean("T1");
userT.show();
}
4.结果
3、发现
如果你在无参构造里加输出语句,会在你每次加载xml文件时,就输出来,这说明:在配置文件接在的时候,容器中管理的对象就已经初始化了
相关资源: 学习狂神说 学习地址(以上仅为笔记)