一、IOC/DI理解
控制反转IoC(Inversion of Control):
从字面上来解释下:
控制:指以前由程序本身来控制,而现在这种权力转移给了IoC容器(Spring)来创建对象,你要什么对象,它就给你什么对象。有了这个中间的IoC容器后,原先的依赖关系就没了,它们都依赖IoC容器了,通过IoC容器来建立它们之间的关系。低耦合了。
什么叫正转?指程序自己来创建对象。
反转:程序不创建对象,变为了被动接受对象(由Spring来创建)。
DI(依赖注入):
其实是IOC的另外一种说法,DI是由Martin Fowler 在2004年初的一篇论文中首次提出的。他总结:控制的什么被反转了?就是:获得依赖对象的方式反转了。
二、Spring代码示例
通过代码实例来更好的理解下。开发环境:Eclipse。
- 创建一个java项目
项目取名:01spring_ioc
点Finish创建成功。 - Dao接口类
新建Package(包)
备注:
一、java项目包名规范
1)个体项目:
indi :
个体项目,指个人发起,但非自己独自完成的项目,可公开或私有项目,copyright主要属于发起者。
包名为“indi.发起者名.项目名.模块名.……”。
pers :
个人项目,指个人发起,独自完成,可分享的项目,copyright主要属于个人。
包名为“pers.个人名.项目名.模块名.……”。
priv :
私有项目,指个人发起,独自完成,非公开的私人使用的项目,copyright属于个人。
包名为“priv.个人名.项目名.模块名.……”。
2)团队项目:
team :
团队项目,指由团队发起,并由该团队开发的项目,copyright属于该团队所有。
包名为“team.团队名.项目名.模块名.……”。
com :
公司项目,copyright由项目发起的公司所有。
包名为“com.公司名.项目名.模块名.……”。
二、java常见的包名
取名:priv.ioc.dao
新建接口:UserDao
代码:
package priv.ioc.dao;
public interface UserDao {
public void getUser();//getUser接口
}
- Dao实现类
新建包priv.ioc.dao.impl和2个类UserDaoMySqlImpl、UserDaoOracleImpl,增加实现类代码
package priv.ioc.dao.impl;
import priv.ioc.dao.UserDao;
public class UserDaoMySqlImpl implements UserDao{
@Override
public void getUser() {
System.out.println("mysql获取用户数据");
}
}
package priv.ioc.dao.impl;
import priv.ioc.dao.UserDao;
public class UserDaoOracleImpl implements UserDao{
@Override
public void getUser() {
System.out.println("oracle获取用户数据");
}
}
- Service接口类
增加service接口包priv.ioc.service和接口类UserService
package priv.ioc.service;
public interface UserService {
public void getUser();
}
-
Service实现类
增加service实现包priv.ioc.service.impl和实现类UserServiceImpl
-
Test测试类
新建测试包priv.ioc.test和测试类Test
Test类
一、通过非IOC方法直接调用,实现代码:
package priv.ioc.test;
import priv.ioc.dao.impl.UserDaoMySqlImpl;
import priv.ioc.dao.impl.UserDaoOracleImpl;
import priv.ioc.service.impl.UserServiceImpl;
public class Test {
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
userService.setUserDao(new UserDaoMySqlImpl());
userService.getUser();
System.out.println("-----------------");
userService.setUserDao(new UserDaoOracleImpl());
userService.getUser();
}
}
项目结构如下:
运行,结果显示:
mysql获取用户数据
-----------------
oracle获取用户数据
备注:
如果运行时出现这种错误:
错误:在类XXX中找不到 main 方法, 请将 main 方法定义为: public static void main(String[] args) 否则 JavaFX 应用程序类必须扩展javafx.application.Application
**解决方法:**设置每次运行或调试前自动保存编辑的内容:
Preferences/Launching/Save required dirty editors before launching改成Always。
二、使用IOC方法调用,实现代码
要先引入spring-framework库。 Spring-framework下载请参考:[Spring学习]02 Spring-framework下载指引
先创建xml文件,如: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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--创建dao的实例对象-->
<bean id="mysqlDao" class="priv.ioc.dao.impl.UserDaoMySqlImpl"> </bean>
<bean id="oracleDao" class="priv.ioc.dao.impl.UserDaoOracleImpl"></bean>
<!--创建service的实例对象 体现出IOC:控制反转-->
<bean id="service" class="priv.ioc.service.impl.UserServiceImpl">
<!--调用set方法 为属性dao赋值 体现出DI:依赖注入-->
<property name="UserDao" ref="oracleDao"/>
</bean>
</beans>
然后修改Test类中的代码:
package priv.ioc.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
//import priv.ioc.dao.impl.UserDaoMySqlImpl;
//import priv.ioc.dao.impl.UserDaoOracleImpl;
import priv.ioc.service.UserService;
//import priv.ioc.service.impl.UserServiceImpl;
public class Test {
public static void main(String[] args) {
// UserServiceImpl userService = new UserServiceImpl();
// userService.setUserDao(new UserDaoMySqlImpl());
// userService.getUser();
// System.out.println("-----------------");
// userService.setUserDao(new UserDaoOracleImpl());
// userService.getUser();
//1.加载spring配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); //ClassPathXmlApplicationContext("Beans.xml");
//2.实例化service这个bean
UserService userService = (UserService)context.getBean("service");
userService.getUser();
}
}
项目对应目录和运行结果:
从上面二种调用方式,对IOC的理解应该是一目了然。多动手写一遍,会加深印象的。