IOC
控制反转(Inversion of Control,缩写为IoC)
如果程序写死,那么用户每提出一个新的要求,程序员都需要修改源代码。
比如,现在有教师类Teacher和学生类Student
那么,用户要获取教师时候,伪代码为
public class UserServiceImpl implements UserService{ private UserDao userDao = new Teacher(); public void getUser() { userDao.getUser(); } }
如果现在要获取学生,就需要更改源代码
public class UserServiceImpl implements UserService{ private UserDao userDao = new Student(); public void getUser() { userDao.getUser(); } }
很不方便,于是,改变写法
public class UserServiceImpl implements UserService{ private UserDao userDao;
//利用set方法实现值的动态注入 public setUserDao(UserDao userDao){ this.userDao = uerDao; } public void getUser() { userDao.getUser(); } }
在用户调用的时候
UserService userService = new UserServiceImpl(); userService.setUserDao(new Teacher()); //serService.setUserDao(new Student()); userService.getUser();
在这之前,程序员需要主动创建对象,控制权在程序员手上,如:
private UserDao userDao = new Student();
用了set之后,程序员不需要主动创建对象,而是程序被动的接收对象,如:
userService.setUserDao(new Teacher());
在这个过程中,控制权发生了转变,既实现了控制反转
之前的主动权在于业务层,程序员选择调用什么
更改代码之后的主动权在于用户,用户选择调用什么
控制反转定义:
控制反转是一种通过描述(XML或注解)并通过第三方生产或者获取特定对象的方式,在Spring中实现控制反转的是IoC容器,其实现方式是依赖注入(DI)
下面看一个在Spring中的例子
首先创建一个beans.xml
<!--在Spring中创建对象,这些对象在Spring中称为Bean 之前创建对象: 类型 变量名 = new 类型(); Hello hello = new Hello(); 在这里 id相当于变量名 class相当于new的对象 property相当于对象的属性值 --> <bean id="hello" class="com.src.Hello"> <property name="str" value="Spring" /> </bean>
在XML中写好之后,如何在类中使用,在Hello类中,要有一个setStr方法
//解析beans.xml文件,生成相应的Bean对象
ApplicationContext context = newClassPathXmlApplicationContext("beans.xml"); //getBean的参数即为配置文件中的bean的id Hello hello = (Hello) context.getBean("hello");
//不想用强转的话,就传入第二个参数
//Hello hello = context.getBean("hello",Hello.class);
控制反转:创建对象的时候,之前由程序员写new从而创建新的对象,而现在通过Spring来创建,也就是程序本身不创建对象,而是被动接收对象
依赖注入:通过set方法进行注入
如果现在想创建对象,就不需在程序中new了,而是去xml文件中修改
Spring的IoC概念就是:对象由Spring创建,管理,装配
大致步骤如下
1、获取Spring容器
ApplicationContext context = new ClassPathXmlApplicationContext( "beans.xml");
2、通过getBean方法在容器中找到自己想要的对象
User user = (User) context.getBean("user");
实现了IOC
其中,bean的配置,类中的属性可以通过name来设定
<bean id="hello" class="com.lee.pojo.Hello"> <property name="str" value="Spring"/> </bean> <bean id="user" class="com.lee.pojo.User"> <property name="name" value="userName"/> </bean>
Spring的其他配置
alias:别名 ,此时hello和hhh是等价的,都代表Hello的对象,即 context.getBean("hello"); context.getBean("hhh");取到的都是一个对象
除此外,还可以在bean标签中的name属性起别名,并且可以取多个别名,多个别名之间可通过空格和逗号或分号分割。此时hello、hello2、hhh都代表一个对象
<bean id="hello" class="com.lee.pojo.Hello"name="hello2">
<property name="str" value="Spring"/>
</bean>
<alias name="hello" alias="hhh"/>
import: 导入 通常用于多人开发,具体作用就是将其他人的xml导入到一个总的xml中,进行汇总,用的时候直接导入总的就行了
比如总的xml文件叫 applicationContext.xml,但现在需要beans.xml中的bean,那么就通过import将beans.xml导进来,用的时候直接
ApplicationContext context = new ClassPathXmlApplicationContext( "applicationContext.xml");
这样,即便是beans.xml中的bean也能导入进来
<bean id="hello" class="com.lee.pojo.Hello"name="hello2"> <property name="str" value="Spring"/> </bean> <import resource="beans.xml"/>