Spring框架总结(二):Spring Ioc(控制反转)简单开发及源码剖析
Spring官方文档对依赖注入(DI)的解释:
依赖注入(DI)是一个过程,通过这种过程,对象可以通过构造函数参数,工厂方法参数或者在构造或返回对象实例后设置的属性来定义它们的依赖关系,也就是说,它们使用的其他对象从工厂方法。容器在创建bean时会注入这些依赖关系。这个过程从根本上说是相反的,因此名为控制反转(IoC),它本身通过使用类的直接构造或服务定位器模式来控制它自己的依赖关系的实例化或位置。
上次主要编写使用Spring容器获取javabean,但理想情况下,应用程序代码不应该使用它们。事实上,你的应用程序代码根本不应该调用该 getBean()
方法,因此完全不依赖于Spring API。例如,Conroller中的Servlet对象应该是依赖于Service对象,Service依赖Dao对象,这些不应该我们去创建的,而是应该Spring去完成,这就是依赖注入.
DI存在两种主要的类型,基于构造函数的注入和基于setter 的注入。
基于setter的注入
基于Setter的 DI通过调用无参数构造函数或无参数static工厂方法来实例化bean之后,调用bean上的容器调用setter方法来完成。
编写Action类,他依赖UserService,必须要有set方法,这次我们交给Spring来注入这个属性
package sdibt.fly.controller;
import sdibt.fly.service.UserService;
public class UserAction {
private UserService userService;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public void addUser(){
userService.addUser();
}
}
UserService:
package sdibt.fly.service;
public class UserService {
public void addUser(){
System.out.println("addUser----------");
}
}
配置applicationContext.xml:
userAction下有个property标签,表示依赖的对象。name代表属性的名字,ref代表依赖对象的id
<?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"
>
<!-- User实体类对象,id唯一标识这个对象 -->
<bean id="user" class="sdibt.fly.entity.User" scope="singleton"></bean>
<!-- 配置action,注入UserService -->
<bean id="userAction" class="sdibt.fly.controller.UserAction">
<property name="userService" ref="userService"></property>
</bean>
<bean id="userService" class="sdibt.fly.service.UserService"></bean>
</beans>
测试一下
package sdibt.fly.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import sdibt.fly.controller.UserAction;
public class TestIoc {
public static void main(String[] args) {
//加载配置文件
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//通过id来获取bean对象
UserAction userAction = (UserAction) ctx.getBean("userAction");
userAction.addUser();
}
}
ok。成功注入!
属性类型是集合或者数组等如何注入
<bean id="user" class="sdibt.group.entity.User" scope="prototype">
<!-- user依赖int,string -->
<property name="username" value="xiaoming"></property>
<property name="id" value="1"></property>
<property name="addresses">
<list>
<value>yantai</value>
<value>beijing</value>
</list>
</property>
</bean>
基于构造函数的注入
更改action类,把get,set 方法去掉,使用一个带参数的构造函数给对象注入,不过除了要写带参数的构造参数外,还要有一个无参的构造参数。
package sdibt.fly.controller;
import sdibt.fly.service.UserService;
public class UserAction {
public UserAction(){
}
public UserAction(UserService userService) {
this.userService = userService;
}
private UserService userService;
public void addUser(){
userService.addUser();
}
}
xml配置文件
<constructor-arg name="userService" ref="userService"></constructor-arg>
<?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"
>
<!-- 配置action,注入UserService -->
<bean id="userAction" class="sdibt.fly.controller.UserAction">
<constructor-arg name="userService" ref="userService"></constructor-arg>
</bean>
<bean id="userService" class="sdibt.fly.service.UserService"></bean>
</beans>
自动装配
不用配置依赖关系,自动装配,基于setter的自动注入,就是必须要有set方法,我们只需把bean配置好,Spring就会自动装配,自动装配的两种方式:
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"
default-autowire="byName"
>
<!-- 配置action,注入UserService -->
<bean id="userAction" class="sdibt.fly.controller.UserAction"></bean>
<bean id="userService" class="sdibt.fly.service.UserService"></bean>
</beans>
1.default-autowire="byName"
默认的装配方式:默认是不自动装配,byName是根据名字自动装配,action的属性名和xml的id一致,就会自动装配
2.default-autowire="byType"这一种是根据类型装配,属性名和id名可以不一致,会根据类型自动装配
private UserService userService;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}