IOC本意是控制反转,依赖注入,反转的是产生对象的方式,以前我们产生对象需要进行new,但是现在只new一个工厂,然后通过工厂的getBean(name)直接获取就行,一种工厂模式,将new方法以bean的方式注入一个ioc容器当中,你需要哪个传入名字,直接获取就行,便于管理维护。
总结一句话:获取什么对象,直接从容器当中拿,无需自己制造。当然准备工作必须要把类注入到容易当中。
那么ioc本质是为了解决什么问题呢?
在以前,我们如果不想new对象,可以自己写一个工厂,对很多个类进行统一化管理,根据传入的参数,然后生产出相应的对象给用户,但是你在工厂当中实际上还是需要new对象,并且这个工厂里面你为了返回不同的类,肯定有很多个if,else语句,那么每当你增加了一个类的时候,就要添加一个if,else语句,并在工厂的其他地方也进行修改,这很不方便,所以就有了ioc来帮我们解决这个问题,你只需要在xml文件之中配置你的类,之后一切的操作你都不用管了,直接用就行了
下面是一个ioc的例子:
ICourse接口,放置一个抽象方法
package entity; public interface ICourse { public void learn(); }
HtmlCourse
public class HtmlCourse implements ICourse{ public void learn(){ System.out.println("学习html.."); } }
JavaCourse,Student
public class JavaCourse implements ICourse{ public void learn(){ System.out.println("学习java.."); } }
public class Student { public void learn(String name){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); ICourse iCourse = (ICourse)context.getBean(name); //根据传入课程的名字从容器中获取对象,然后调用learn方法 iCourse.learn(); }
}
接下来将这三个类注入到容器当中:
application.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="student" class="entity.Student"> <property name="stuAge" value="15"/> <property name="stuName" value="ennio"/> <property name="stuNo" value="1"/> </bean> <bean id="htmlCourse" class="entity.HtmlCourse"/> <bean id="javaCourse" class="entity.JavaCourse"/> </beans>
书写测试类进行测试
public class Test { public static void main(String[] args){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Student student = (Student)context.getBean("student"); student.learn("htmlCourse"); } }
可以看到,学习哪个课程直接传入课程名字就行,
对于容器配置有一点需要说明:
如果需要注入非简单类型数据,将value属性替换为 ref="对应的数据id"
下面是依赖注入的三种方式:
1.比如这一行注入数据<property name="stuNo" value="1"/>,是通过调用相应类的set方法进行的
2.通过构造方法注入 如图:
<bean id="student" class="entity.Student"> <constructor-arg value="12"/> <constructor-arg value="ennio"/> <constructor-arg value="1"/> </bean>
不想按照顺序写指定name也可以
3.给集合类赋值
很简单,采用的是类似<list><value/></list> 的方式,会有提示,跟着写就行,注意一下map的方式就行:如下
<map> <entry> <key> <value>str</value> </key> <value>dsadsa</value> </entry> <entry> <key> <value>str2</value> </key> <value>dsadsa22</value> </entry> </map>
几点细节:
1.不使用子元素进行赋值时,value需要用双引号括起来,并且一些特殊符号不能直接写,需要进行替换,比如 < 要写成 &It; & 要写成 &,如果用双引号括起来的话,则可以使用<![CDATA[.....]]>将数据括起来,则中间可以随便写,不需要转换
2.赋空值:
null: 使用<null/> 并且不需要写<value>标签
空字符串: ""里面什么都不写就行