Spring学习——DI(依赖注入)
IOC容器,处理对象依赖关系
IOC与DI:
IOC :是一个容器,创建对象的容器
DI :在容器创建对象后,处理对象的依赖关系,也叫依赖注入!
方式1:通过set方法注入值
可以给普通属性、集合属性注入值:
1. 必须提供set方法
2. 配置中通过bean的property子节点,给对象属性注入值;
1 <!-- 2 依赖注入,即处理对象的依赖关系!给对象的属性设置值! 3 --> 4 <!-- 1) 给对象属性赋值(通过构造函数)--> 5 <bean id="user1" class="cn.andy.d_di.User"> 6 <constructor-arg index="0" value="1000"></constructor-arg> 7 <constructor-arg index="1" value="Jack"></constructor-arg> 8 </bean> 9 10 <!-- 2)给对象属性赋值, 通过set方法 --> 11 <bean id="user2" class="cn.andy.d_di.User"> 12 <property name="id" value="100"></property> 13 <property name="name" value="Jacky"></property> 14 </bean> 15 16 <!-- 通过set方法, 给list集合属性注入值 --> 17 <bean id="user3" class="cn.andy.d_di.User"> 18 <property name="list"> 19 <list> 20 <value>中国</value> 21 <value>美国</value> 22 </list> 23 </property> 24 </bean> 25 26 <!-- 通过set方法,给map集合注入值 --> 27 <bean id="user4" class="cn.andy.d_di.User"> 28 <property name="map"> 29 <map> 30 <entry key="cn" value="中国"></entry> 31 <entry key="usa" value="美国"></entry> 32 </map> 33 </property> 34 </bean> 35 36 <!-- 通过set方法,给Properties注入值 --> 37 <bean id="user" class="cn.andy.d_di.User"> 38 <property name="prop"> 39 <props> 40 <prop key="cn">中国</prop> 41 <prop key="usa">美国</prop> 42 </props> 43 </property> 44 </bean>
依赖注入,处理dao/service/action依赖关系:
1 <!-- 1. 创建dao/service/action对象; 2. 依赖注入 --> 2 <bean id="userdao" class="cn.andy.e_eg.UserDao"></bean> 3 <bean id="userservice" class="cn.andy.e_eg.UserService"> 4 <property name="userDao" ref="userdao"></property> 5 </bean> 6 <bean id="userAction" class="cn.andy.e_eg.UserAction" scope="prototype"> 7 <property name="userService" ref="userservice"></property> 8 </bean>
方式2: 内部bean:
1 <!-- 适合: 当创建的bean只用一次,可以用内部bean写法 --> 2 <bean id="userAction" class="cn.andy.e_eg2.UserAction"> 3 <property name="userService"> 4 <bean class="cn.andy.e_eg2.UserService"> 5 <property name="userDao"> 6 <bean class="cn.andy.e_eg2.UserDao"></bean> 7 </property> 8 </bean> 9 </property> 10 </bean>
内部bean特点:
1. 写法紧凑
2. 不通用, 内部bean只能被当前的bean使用,别的bean引用不了!
方式3: p名称空间注入值:
<!-- 1. 要先引入p名称空间; 2. spring3.0以上版本才可以 --> <bean id="userdao" class="cn.andy.f_p.UserDao"></bean> <bean id="userService" class="cn.andy.f_p.UserService" p:userDao-ref="userdao"></bean> <bean id="userAction" class="cn.andy.f_p.UserAction" p:userService-ref="userService"></bean>
方式4: 自动装配:
方式4.1: 根据名称自动装配(autowire="byName")
会去容器找指定属性名称,注入到对象中(通过set方法注入)
1 <bean id="userDao" class="cn.andy.g_auto.UserDao"></bean> 2 <bean id="userService" class="cn.andy.g_auto.UserService" autowire="byName"></bean> 3 <bean id="userAction" class="cn.andy.g_auto.UserAction" scope="prototype" autowire="byName"></bean>
方式4.2: 根据类型自动装配(autowire="byType")
1. 当根据类型自动装配,会去容器找改类型的对象,再自动注入
2. 该类型在容器中必须只有一个实例,唯一!
1 <bean id="userDao1" class="cn.andy.g_auto.UserDao"></bean> 2 <bean id="userservice" class="cn.andy.g_auto.UserService" autowire="byType"></bean> 3 <bean id="userAction" class="cn.andy.g_auto.UserAction" scope="prototype" autowire="byType"></bean>
方式4.3: 全局自动装配(default-autowire="byType"或default-autowire="byName")
定义到根节点,表示所有的bean都使用自动装配:根据名称或类型
1 <beans xmlns="http://www.springframework.org/schema/beans" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns:p="http://www.springframework.org/schema/p" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byType">
自动装配总结:
1. 写法简单;
2. 不利于维护,出错不好排查!
方式5: 基于注解方式处理对象依赖关系:
注解,可以简化配置!提升开发效率,但是不利于后期维护!
@Component 把对象加入ioc容器,对象引用名称是类名,第一个字母小写
@Component(“name”) 把指定名称的对象,加入ioc容器
@Repository, 主要用于标识加入容器的对象是一个持久层的组件(类)
@Service , 主要用于标识加入容器的对象是一个业务逻辑层的组件
@Controller, 主要用于标识加入容器的对象是一个控制层的组件
@Resource 注入属性(DI), 会从容器中找对象注入到@Resource修饰的对象上!
1 <!-- 2 步骤: 3 1. 引入context名称空间 4 2. 开启注解扫描 5 3. 使用注解 6 --> 7 xmlns:context="http://www.springframework.org/schema/context" 8 ... 9 http://www.springframework.org/schema/context 10 http://www.springframework.org/schema/context/spring-context.xsd"> 11 ... 12 <context:component-scan base-package="cn.andy.***"></context:component-scan>
使用注解实例:
1 //注解实例 2 @Controller 3 @Scope("prototype") // 指定为多例, 默认为singleton 4 public class UserAction { 5 @Resource // 根据下面属性名称,去容器里面找对应的对象, 找到后注入进来 6 private IUserService userService; 7 8 public String execute() { 9 userService.save(); 10 return "success"; 11 } 12 }
注解与配置比较:
注解,简化配置,开发快捷高效!
配置,开发繁琐、配置麻烦,容易维护!