Spring是什么?简单的说就是轻量级的开源框架,其核心是Ioc(控制反转)和AOP(面向切面编程)。它同时也提供了两个核心容器,BeanFactory和ApplicationContext.在实际开发中,会倾向于使用后者。
入门程序,写一个hello world(准备工作就跳过)
dao层:
public class UserDao {
public void say() {
System.out.println("hello world");
}
}
applicationContext.xml
<bean id="userDao" class="cn.edu.nsu.dao.UserDao"></bean>
测试:
public class test {
@Test
public void fun() {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao=(UserDao)context.getBean("userDao");
userDao.say();
}
}
输出结果:
可以看到,通过在配置文件使用bean属性,我们创建了一个UserDao的实例,其id为userDao,在测试数据层,使用ApplicationContext容器获取到xml文件,并调用getBean方法得到实例对象,最后调用say()方法打印出hello world。
这个过程,其实就是IoC(控制反转),其本质就是将控制权从代码转交给spring容器。
那么,什么是DI(依赖注入)呢?
在上面的基础上,新添UserService类
public class UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void say() {
userDao.say();
}
}
修改applicationContext.xml如下
<bean id="userDao" class="cn.edu.nsu.dao.UserDao"></bean>
<bean id="userService" class="cn.edu.nsu.service.UserService">
<property name="userDao" ref="userDao"></property>
</bean>
修改测试层如下
public class test {
@Test
public void fun() {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService=(UserService)context.getBean("userService");
userService.say();
}
}
最后测试发现,会得到和预期一样的结果。仔细研究可以看出:我们在applicationContext.xml中将UserDao和UserService分别实例化,同时利用property将UserDao作为一个属性注入到UserService中。最后在测试层实例化UserService,并调用say()方法打印hello world。
那么,使用依赖注入有没有什么限制呢?有的!被注入的对象(即本例中的UserService)必须要有无参构造和setter方法,这也是Bean的基本属性。
说了这么多,其实就是想说明一点,DI和IoC的含义是一样的,都是避免直接使用new来创建对象,达到减少耦合度的目的,但是从不同的角度看待就会不一样,但是其本质是一样的。