您的位置:首页 > 编程语言 > Java开发

深入解析spring的IOC和DI

2015-07-05 14:42 751 查看
在此之前先说一下没有的时候,对象直接的合作是如果工作的,比如A类要调用B类的方法,首先在A类中肯定需要创建一个B对象,然后通过B对象的实例去调用方法的实例方法,如是静态方法可以直接通过类名去调用即可。这样做的缺点,通过new对象的的方式去创建对象,第一相互之间的依赖性太大,同一个对象多次创建,用完以后需要销毁,效率低下,这样的方式总体就是,对象之间的耦合度高,效率低(每次都需要创建和销毁对象

Spring的出现就是为了解决这些问题的,在次之前也有过类似这样的框架,那就是EJB (Enterprise JavaBean),根据业务需求定义不同类型的bean,但是这种方式及其繁琐,而且很难理解和学习,spring的出现基本完全替代了EJB,spring注意有两大块,一个是IOC和DI(反转控制依赖注入),还有就是aop面向切面编程),这里重点讲解spring的IOC和DI

Spring IOC就是反转控制,由spring去生成对象,不再有对象需要的时候去创建和销毁,由spring去控制对象的生命周期,把对呀的一切都交个spring来管理,这就是反转控制。那么依赖注入又是怎么回事呢,通过研究发现其实spring是把对象的创建的整个过程反转了,那对象创建的过程肯定就包含了他对象的属性,比如创建A对象的时候,A对象需要调用B对象的某个实例方法,那就必须在创建的时候把B对象注入给A对象,这样A对象才算是一个我们想要的对象,其实吧B对象注入给A对象的过程就是依赖注入,说到底就是为了创建一个完整的A对象,而需要给A对象的某个属性(B对象的实例)赋值,那么推而广之,所有的对象都是由spring来创建,都有spring来管理,都有spring来注入,这就是spring的ioc的最基本的思想,

实例解析spring的依赖注入。就比如现在一个请求发送到controller,controller需要调用service对象的方法,而service又需要调用dao的方法,那么其实在创建controller对象的时候就应该吧service对象注入个action,但是service对象创建的时候又需要把dao对象注入给service,所以当请求到了controller我们就直接能得到数据和操作数据库的数据,而不用管底层是怎么样实现的,底层dao操作数据库是通过jdbc还是hibernate 还是mybatis都没关心,包括操作数据库对象的一些对象比如Connection对象是何时创建何时销毁,我们都不需要关心,这一点是完全没有违背oop思想的。

注入的实现,那既然A对需要得到B对象的实例,那在A对象肯定是需要一个B类型的属性作为B对象的实例载体,然后才能把B对象注入给A对象的这个B对象的载体的属性,那注入分为配置文件的注入和注解注入,在spring2.x和之前更早的版本只能通过配置文件的方式注入在之后才支持注解的注入,首先讲解配置文件方式的注入,这也更能体现依赖注入的原理,比如我现在定义一个UserService和一个UserDao,现在要把dao注入给service,那首先要早UserService中第一个一个用于接受UserDao的属性,因为通过配置注入,所以该属性必须对外提供set方法,然后在配置文件通过该方法注入dao对象,注意属性名一定是service的属性名称,同时也要求service中的属性和对应的set方法必须按照标准的属性来命名。属性值必须是spring已经存在的对象,不能是没有交给spring管理的类。





扩展一点,其实不仅仅可以注入对象属性,一般的简单属性也是可以注入的额,比如注入一个Integer,List也可以注入的,简单属性的注入通过value注入,复杂属性(对象属性)通过ref注入。

代码实现:

xml配置
<!-- userDao -->
<bean id="userDao" class="cn.dome.dao.UserDao" />

<!-- userService -->
<bean id="userService" class="cn.dome.service.UserService">
<!-- 对象注入 -->
<property name="userDao" ref="userDao"></property>
<!-- 字符串属性注入 -->
<property name="userName" value="张三"></property>
<!-- 简单属性注入 -->
<property name="age" value="23"></property>
<p
</bean>


UserService
package cn.dome.service;

import cn.dome.service.UserDao;

public class UserService {
//UserDao对象
private UserDao userDao;
//姓名(属性)
private String userName;
//年龄(属性)
private Integer age;

public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void setUserName(String userName) {
this.userName = userName;
}
public void setAge(Integer age) {
this.age = age;
}
public void delete(Integer id){
userDao.delete(id);
}
}
</pre><pre name="code" class="html">UserDao代码
package cn.dome.dao;
public class UserDao {
public void delete(Integer id) {
}
}


注解注入,注解注入是spring2.0之后才有的注入方式,好处是不需要写繁琐的配置文件,公共组件注解,就能把一个普通的类交给spring管理,又spring生成和分配,然后通过注入注解就能把一个指定的对象注入给该对象的某个属性,注解注入的方式有通过名称注入,通过名称注入,必须要求组件注解上给出对应的名称,才能通过名称注入,第二种是通过类型注入,只需要类型匹配就可以注入,但是如果通过接口应用实现类,如果接口有多个实现类,通过类型注入则会报错,第三种是通过类型和名称的混合注入,这样可以通过接口去应用实现类,但实现类必须有名称,注解可以减少繁琐的xml配置的编写,只需要开启注解驱动即可

xml配置
<!-- 开启注解扫面 -->
<context:component-scan base-package="cn.dome" />
</pre><p></p><span style="font-family:宋体"></span><pre name="code" class="html">UserDao代码
package cn.dome.dao;

import org.springframework.stereotype.Component;

@Component
public class UserDao {
public void delete(Integer id) {
}
}
</pre><pre name="code" class="html">UserService代码
package cn.dome.<span style="font-family: 宋体;">service</span><span style="font-family: 宋体;">;</span>

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.dome.service.UserDao;

@Service
public class UserService {
@Autowired
private UserDao userDao;
public void delete(Integer id){
userDao.delete(id);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: