Spring框架IOC学习
1.我们一开始最原始写代码,如果要在一个类中调用另一个类,必须先实例化被调用的对象(new对象)才能使用,写个例子。
1)dao层
接口:
public interface UserDao { void getUser(); }
实现类:
public class UserDaoImpl implements UserDao { public void getUser() { System.out.println("这是一个数据"); } }
2)service层
接口:
public interface UserService { void getUser(); }
实现类:
public class UserServiceImpl implements UserService { private UserDao userDao = new UserDaoImpl(); public void getUser() { userDao.getUser(); } }
3)测试类
public class MyTest { public static void main(String[] args) { UserService userService = new UserServiceImpl(); userService.getUser(); } }
这时如果如果dao层有改动,多了一个实现类:
public class UserDaoMysqlImpl implements UserDao{ public void getUser() { System.out.println("Mysql"); } }
现在我们要用这个实现类,那么我们就必须修改service中实例化的对象也就是将:
private UserDao userDao = new UserDaoImpl(); 改为 private UserDao userDao = new UserDaoMysqlImpl();
这显然违反我们java开发的开闭原则,开闭原则,对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的。
那么如何修改我们的程序达到不用修改service层就能实现以上的效果呢?我们可以使用set注入,修改代码如下:
public class UserServiceImpl implements UserService { private UserDao userDao; //利用set进行动态实现值的注入! public void setUserDao(UserDao userDao){ this.userDao = userDao; } public void getUser() { userDao.getUser(); } }
我们在使用时可以直接通过set来注入:
public class MyTest2 { public static void main(String[] args) { UserService userService = new UserServiceImpl(); //((UserServiceImpl) userService).setUserDao(new UserDaoImpl()); ((UserServiceImpl) userService).setUserDao(new UserDaoOracleImpl()); userService.getUser(); } }
这就是一个最原始的ioc的雏形,它使得之前程序主导创建对象的情况变成了程序被动注入,实现了控制反转。
我们先用配置xml的方式来实现Spring bean对象的管理:
在resources文件夹中创建applicationContext.xml(名字可以随便取,但是Spirng官方文档中叫这个名字),并添加bean对象。
<?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就是spring为我们实例化的对象 原来是 类型 变量名 = new 类型(); bean就相当于这个过程 bean标签里面的参数id就是变量名 class指向全路径,你new的对象路径。 --> <bean id="mysqlImpl" class="com.kuang.dao.UserDaoMysqlImpl"></bean>
<bean id="UserServiceImpl" class="com.kuang.service.UserServiceImpl"> <!-- ref:引用Spring容器中已经创建好的对象 value:具体的值,基本数据类型 --> <property name="userDao" ref="mysqlImpl"></property> </bean> </beans>
Spring官方为我们提供了ClassPathXmlApplicationContext类来获取容器:
public class MyTest { public static void main(String[] args) { //获取ApplicationContext:拿到Spring的容器 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //容器在手,天下我有,需要什么,就直接get什么 UserServiceImpl userServiceImpl = (UserServiceImpl) context.getBean("UserServiceImpl"); userServiceImpl.getUser(); } }
一句话总结IOC本质:对象由Spring 来创建 , 管理 , 装配 。