Spring的IOC与DI

前言

先讲一下Spring的产生,因为之前的博客直接简单模拟了Spring,觉得比较唐突,毕竟有些人还不理解Spring用来干嘛,所以在这里详细讲解一下Spring

Spring的IOC与DI
这是百度百科的解释,我就通俗的讲一下,Spring中有两个核心,一个是IOC(控制反转),一个是AOP(面向切面)

IOC(控制反转)

先说一个场景,比如我有一个类,这个类里面有个方法,而这个类是用于数据库持久层的,那就意味着如果工程需要我就要改变这个数据库持久层的实现方式,以前使用mysql,现在要用oracle,那么我就要改变这个类,同时改变使用这个类的类,说的有点迷糊,我用代码来讲吧:

User类
Spring的IOC与DI
假如这个User类就是数据库持久层,此时用mysql实现,fun()代表对数据库的一大堆操作,假如由于数据库改为oracle,那么我就要写一个新的类用于数据库持久层,如果数据库持久层方式很多的话,就要很多的类,而且每改一次就要改变源代码,这绝对不符合我们JAVA的开闭原则

当然会有人说,我可以用接口实现,到时候传入一个接口的实现类就行了,这种方法的确比上面的好,但同样,它还是改变不了如果这个类要改变,你传入的实现类还是要改变,还是需要修改源码,也不符合开闭原则

那么还能改进,我可以不直接通过接口和实现类 new出来对象,我可以在接口和实现类中间增加一个工厂,所有的对象都从工厂中取得,这避免了在使用这个类的对象的时候,如果类改变对象也要改变的弊端,但是如果增加新类,工厂中就要增加新的get方法,来返回这个类的对象,这同样是不符合开闭原则

Spring呢,就是整合了以上的思路,它采用了在这里插入图片描述
Spring的IOC与DI
这就是Spring IOC的底层实现思想,采用工厂模式+反射机制+配置文件,达到改变实现类的话,只需要改变配置文件,而不需要修改源码的目的,下面用简单的配置来实现一下

导入Spring的jar包
有个网址是:
http://repo.springsource.org/libs-release-local/org/springframework/spring
选择你需要版本的Spring jar包,然后在dist.zip中找到以下几个核心jar包,
Spring的IOC与DI
导包就行了,

创建接口类和实现类

package com.mec.spring.core;

public interface IUser {
	
	public void fun1();
}

public class User1 implements IUser {

	@Override
	public void fun1() {
		System.out.println("User中的fun1方法执行");
	}

}

XML配置
在src目录下建立一个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-3.0.xsd">  
 //前面为制式的配置,直接找到Spring的文档然后复制粘贴就好
  <bean id = "iuser"  class = "com.mec.spring.core.User1"></bean>
 //这个bean就代表从工厂中取得一个bean,id可以为接口名,class为实现类带包名的类名
  </beans>

测试类

public class Test {

	public static void main(String[] args) {
		//这个ApplicationContext可以理解为之前所说的Beanfactory
		//ClassPathXmlApplicationContext表明用XML配置方式实现接口与类对应关系
		ApplicationContext ap = new ClassPathXmlApplicationContext("Spring.config.xml");
		//取出一个Bean
		IUser iu = (IUser) ap.getBean("iuser");
		//执行bean的方法
		iu.fun1();
	}

结果图
Spring的IOC与DI

以上就是Spring的IOC,简单来说就是让Spring管理这些类,如果需要对象,导入配置文件后,直接从工厂中取出就行。

DI(依赖注入)

依赖注入的话,我在前面说过,就是说A中有B的依赖,B中有C的依赖,那么如果我们自己来做的话,在碰到依赖的话,就需要有一个set方法给依赖的对象赋值,如果需要很多的依赖,一个一个的赋值势必会很麻烦,那么我们可以把类交给Spring管理,对于其中对象的赋值,我们同样的可以直接通过配置的方式来完成,那么如果值改变,我们也只需要修改配置文件,避免修改源码,下面说一个具体的例子

假如我的类中需要一个String类型的依赖,那么以前的做法是给出set方法供外部设置值,而在Spring接管这个类后,我们只需要这样做

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-3.0.xsd">  

  <bean id = "iuser"  class = "com.mec.spring.core.User1">
	<property  name = "name" value = "wangfei"/>
  </bean>
</beans>

User:

public class User1 implements IUser {
	private String do1;
	@Override
	public void fun1() {
		System.out.println("User中的fun1方法执行"+do1);
	}
	public String getDo1() {
		return do1;
	}
	public void setDo1(String do1) {
		this.do1 = do1;
	}
	
}

这里一定要给出get()和set()方法,网上有些教程不需要也可以执行,应该是版本问题,我用的4.3版Spring,建议在实现类给出get()和set()方法

结果:
Spring的IOC与DI