Spring:IOC本质分析探究
IOC本质分析
分析实现
我们先⽤我们原来的⽅式写⼀段代码
先写⼀个UserDao接⼝
public interface UserDao {
public void getUser();
}
再去写Dao的实现类
1public class UserDaoImpl implements UserDao {
2@Override
3public void getUser(){
4 System.out.println("获取⽤户数据");
5}
6}
然后去写UserService的接⼝
1public interface UserService {
2public void getUser();
3}
最后写Service的实现类
1public class UserServiceImpl implements UserService {
2private UserDao userDao =new UserDaoImpl();
3
4@Override
5public void getUser(){
6 User();
7}
8}
测试⼀下
1@Test
2public void test(){
3 UserService service =new UserServiceImpl();
4 User();
5}
这是我们原来的⽅式 , 开始⼤家也都是这么去写的对吧 . 那我们现在修改⼀下 .
把Userdao的实现类增加⼀个 .
1public class UserDaoMySqlImpl implements UserDao {
2@Override
3public void getUser(){
4 System.out.println("MySql获取⽤户数据");
5}
6}
紧接着我们要去使⽤MySql的话 , 我们就需要去service实现类⾥⾯修改对应的实现 .
1public class UserServiceImpl implements UserService {
2private UserDao userDao =new UserDaoMySqlImpl();
3
4@Override
5public void getUser(){
6 User();
7}
8}
在假设, 我们再增加⼀个Userdao的实现类 .spring ioc注解
1public class UserDaoOracleImpl implements UserDao {
2@Override
3public void getUser(){
4 System.out.println("Oracle获取⽤户数据");
5}
6}
那么我们要使⽤Oracle , ⼜需要去service实现类⾥⾯修改对应的实现 . 假设我们的这种需求⾮常⼤ , 这种⽅式就根本不适⽤了, 甚⾄反⼈类对吧 , 每次变动 , 都需要修改⼤量代码 . 这种设计的耦合性太⾼了, 牵⼀发⽽动全⾝ .
那我们如何去解决呢 ?
我们可以在需要⽤到他的地⽅ , 不去实现它 , ⽽是留出⼀个接⼝ , 利⽤set , 我们去代码⾥修改下 .
1public class UserServiceImpl implements UserService {
2private UserDao userDao;
3// 利⽤set实现
4public void setUserDao(UserDao userDao){
5this.userDao = userDao;
6}
7
8@Override
9public void getUser(){
10 User();
11}
12}
现在去我们的测试类⾥ , 进⾏测试 ;
1@Test
2public void test(){
3 UserServiceImpl service =new UserServiceImpl();
4 service.setUserDao(new UserDaoMySqlImpl());
5 User();
6//那我们现在⼜想⽤Oracle去实现呢
7 service.setUserDao(new UserDaoOracleImpl());
8 User();
9}
⼤家发现了区别没有 ? 可能很多⼈说没啥区别 . 但是同学们 , 他们已经发⽣了根本性的变化 , 很多地⽅都不⼀样了 . 仔细去思考⼀下 , 以前所有东西都是由程序去进⾏控制创建 , ⽽现在是由我们⾃⾏控制创建对象 , 把主动权交给了调⽤者 . 程序不⽤去管怎么创建,怎么实现了 . 它只负责提供⼀个接⼝ .
这种思想 , 从本质上解决了问题 , 我们程序员不再去管理对象的创建了 , 更多的去关注业务的实现 . 耦合性⼤⼤降低 . 这也就是IOC的原型 !
IOC本质
控制反转IoC(Inversion of Control),是⼀种设计思想,DI(依赖注⼊)是实现IoC的⼀种⽅法,也有⼈认为DI只是IoC的另⼀种说法。没有IoC的程序中 , 我们使⽤⾯向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序⾃⼰控制,控制反转后将对象的创建转移给第三⽅,个⼈认为所谓控制反转就是:获得依赖对象的⽅式反转了。
IoC是Spring框架的核⼼内容,使⽤多种⽅式完美的实现了IoC,可以使⽤XML配置,也可以使⽤注解,新版本的Spring也可以零配置实现IoC。
Spring容器在初始化时先读取配置⽂件,根据配置⽂件或元数据创建与组织对象存⼊容器中,程序使⽤时再从Ioc容器中取出需要的对象。
采⽤XML⽅式配置Bean的时候,Bean的定义信息是和实现分离的,⽽采⽤注解的⽅式可以把两者合为⼀体,Bean的定义信息直接以注解的形式定义在实现类中,从⽽达到了零配置的⽬的。
控制反转是⼀种通过描述(XML或注解)并通过第三⽅去⽣产或获取特定对象的⽅式。在Spring中实现控制反转的是IoC容器,其实现⽅法是依赖注⼊(Dependency Injection,DI)。
HelloSpring
1. 导⼊Spring相关jar包
注 : spring 需要导⼊commons-logging进⾏⽇志记录 . 我们利⽤maven , 他会⾃动下载对应的依赖项 .
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.10.RELEASE</version>
</dependency>
2. 编写相关代码
2.1编写⼀个Hello实体类
public class Hello {
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public void show(){
System.out.println("Hello"+ name );
}
}
2.2 写编写我们的spring⽂件 , 这⾥我们命名为l
1<?xml version="1.0" encoding="UTF-8"?>
2<beans xmlns="/schema/beans"
3 xmlns:xsi="/2001/XMLSchema-instance"
4 xsi:schemaLocation="/schema/beans
5 /schema/beans/spring-beans.xsd">
6
7<!--bean就是java对象,由Spring创建和管理-->
8<bean id="hello"class="com.kuang.pojo.Hello">
9<property name="name" value="Spring"/>
10</bean>
11
12</beans>
2.3 我们可以去进⾏测试了 .
@Test
public void test(){
//解析l⽂件 , ⽣成管理相应的Bean对象
ApplicationContext context =newClassPathXmlApplicationContext("l");
//getBean : 参数即为spring配置⽂件中bean的id .
Hello hello =(Hello) Bean("hello");
hello.show();
}
思考问题 ?
Hello 对象是谁创建的 ?
hello 对象是由Spring创建的
Hello 对象的属性是怎么设置的 ?
hello 对象的属性是由Spring容器设置的 ,
这个过程就叫控制反转 :
控制 : 谁来控制对象的创建 , 传统应⽤程序的对象是由程序本⾝控制创建的 , 使⽤Spring后 , 对象是由Spring来创建的 .
反转 : 程序本⾝不创建对象 , ⽽变成被动的接收对象 .
依赖注⼊ : 就是利⽤set⽅法来进⾏注⼊的.
IOC是⼀种编程思想 , 由主动的编程变成被动的接收 .
可以通过newClassPathXmlApplicationContext去浏览⼀下底层源码 .
OK , 到了现在 , 我们彻底不⽤再程序中去改动了 , 要实现不同的操作 , 只需要在xml配置⽂件中进⾏修改 , 所谓的IoC,⼀句话搞定 : 对象由Spring 来创建 , 管理 , 装配 !
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论